# HG changeset patch # User Jie Kang # Date 1506089452 14400 # Node ID 22f2b3ea360945926494c8a424503f873dd1a662 # Parent e67aeba2003a974d916f23e01c9e08eb38e891b9 Add byteman integration services Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/025152.html diff -r e67aeba2003a -r 22f2b3ea3609 distribution/assembly/plugin-assembly.xml --- a/distribution/assembly/plugin-assembly.xml Mon Sep 18 14:04:16 2017 +0200 +++ b/distribution/assembly/plugin-assembly.xml Fri Sep 22 10:10:52 2017 -0400 @@ -57,16 +57,16 @@ com.redhat.thermostat:thermostat-vm-gc-distribution com.redhat.thermostat:thermostat-vm-memory-distribution com.redhat.thermostat:thermostat-vm-io-distribution + com.redhat.thermostat:thermostat-vm-byteman-distribution + com.redhat.thermostat:thermostat-commands-distribution + com.redhat.thermostat:thermostat-killvm-distribution - - com.redhat.thermostat:thermostat-commands-distribution - com.redhat.thermostat:thermostat-killvm-distribution diff -r e67aeba2003a -r 22f2b3ea3609 distribution/pom.xml --- a/distribution/pom.xml Mon Sep 18 14:04:16 2017 +0200 +++ b/distribution/pom.xml Fri Sep 22 10:10:52 2017 -0400 @@ -282,7 +282,6 @@ single - + assemble-scripts @@ -429,7 +428,6 @@ com.redhat.thermostat jnr-x86asm - ${jnr-x86asm.version} com.redhat.thermostat @@ -521,24 +519,24 @@ ${project.version} zip - - - - - - + + com.redhat.thermostat + thermostat-vm-byteman-helper-distro + ${project.version} + zip + + + com.redhat.thermostat + thermostat-vm-byteman-distribution + ${project.version} + zip + - - - - - - - + diff -r e67aeba2003a -r 22f2b3ea3609 plugins/pom.xml --- a/plugins/pom.xml Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/pom.xml Fri Sep 22 10:10:52 2017 -0400 @@ -62,7 +62,7 @@ vm-io vm-memory commands - + vm-byteman diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/pom.xml --- a/plugins/vm-byteman/agent/pom.xml Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/agent/pom.xml Fri Sep 22 10:10:52 2017 -0400 @@ -46,26 +46,6 @@ thermostat-vm-byteman-agent bundle Thermostat VM Byteman Agent plugin - - - skip-byteman-common-test-jar-dep-on-test-skip - - - !maven.test.skip - - - - - - com.redhat.thermostat - thermostat-vm-byteman-common - ${project.version} - test-jar - test - - - - @@ -76,10 +56,12 @@ Red Hat, Inc. com.redhat.thermostat.vm.byteman.agent - + + com.redhat.thermostat.vm.byteman.agent + com.redhat.thermostat.vm.byteman.agent.internal, - com.redhat.thermostat.vm.byteman.agent.internal.typeadapter + com.redhat.thermostat.vm.byteman.agent.internal.typeadapters, <_nouses>true @@ -128,12 +110,7 @@ com.redhat.thermostat - thermostat-vm-byteman-common - ${project.version} - - - com.redhat.thermostat - thermostat-agent-command + thermostat-commands-agent ${project.version} @@ -153,6 +130,11 @@ com.redhat.thermostat + thermostat-jvm-overview-agent + ${project.version} + + + com.redhat.thermostat thermostat-common-test ${project.version} test diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/BytemanMetric.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/BytemanMetric.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,143 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent; + +import java.util.HashMap; +import java.util.Map; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; +import com.redhat.thermostat.storage.core.Entity; +import com.redhat.thermostat.storage.core.Persist; +import com.redhat.thermostat.storage.model.BasePojo; +import com.redhat.thermostat.storage.model.TimeStampedPojo; + +@Entity +public class BytemanMetric extends BasePojo implements TimeStampedPojo { + + private static final Gson GSON = new GsonBuilder().serializeNulls().create(); + public static final String MARKER_NAME = "marker"; + public static final String TIMESTAMP_NAME = "timestamp"; + public static final String DATA_NAME = "data"; + private String jvmId; + private String marker; + private String payload; + private long timestamp; + + public BytemanMetric(String writerId) { + super(writerId); + } + + public BytemanMetric() { + this(null); + } + + @Persist + public String getJvmId() { + return jvmId; + } + + @Persist + public void setJvmId(String jvmId) { + this.jvmId = jvmId; + } + + /** + * Get the marker for this Byteman metric. A marker can be thought of a + * category for related metrics. + * + * @return The marker for this metric. + */ + @Persist + public String getMarker() { + return marker; + } + + @Persist + public void setMarker(String marker) { + this.marker = marker; + } + + @Persist + public void setTimeStamp(long timestamp) { + this.timestamp = timestamp; + } + + @Persist + @Override + public long getTimeStamp() { + return timestamp; + } + + @Persist + public void setData(String json) { + this.payload = json; + } + + @Persist + public String getData() { + return payload; + } + + /** + * Get the metrics payload as raw JSON string. The payload is a JSON object + * in key, value form. Supported value types are {@code Boolean}, + * {@code String} and {@code Double}. + * + * @return The raw JSON string. + */ + public String getDataAsJson() { + return getData(); + } + + /** + * Get the metrics payload as parsed {@link Map}. Supported value types are + * {@code Boolean}, {@code String} and {@code Double}. + * + * @return The parsed JSON payload as {@link Map}. + */ + @SuppressWarnings("unchecked") + public Map getDataAsMap() { + try { + return (Map)GSON.fromJson(payload, HashMap.class); + } catch (JsonSyntaxException e) { + throw new RuntimeException("Payload not in expected format. Payload was: " + payload); + } + } + +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanDAO.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanDAO.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent; + +public interface VmBytemanDAO { + + void addMetric(BytemanMetric metric); + + void addBytemanStatus(VmBytemanStatus status); +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanStatus.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanStatus.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,101 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent; + +import com.redhat.thermostat.storage.core.Entity; +import com.redhat.thermostat.storage.core.Persist; +import com.redhat.thermostat.storage.model.BasePojo; +import com.redhat.thermostat.storage.model.TimeStampedPojo; + +@Entity +public class VmBytemanStatus extends BasePojo implements TimeStampedPojo { + + private String jvmId; + private long timeStamp; + private String rule; + private int listenPort; + + public VmBytemanStatus(String writerId) { + super(writerId); + } + + public VmBytemanStatus() { + super(null); + } + + @Persist + public String getJvmId() { + return jvmId; + } + + @Persist + public void setJvmId(String jvmId) { + this.jvmId = jvmId; + } + + @Persist + public void setTimeStamp(long timestamp) { + this.timeStamp = timestamp; + } + + @Persist + @Override + public long getTimeStamp() { + return timeStamp; + } + + @Persist + public void setRule(String rule) { + this.rule = rule; + } + + @Persist + public String getRule() { + return rule; + } + + @Persist + public void setListenPort(int port) { + this.listenPort = port; + } + + @Persist + public int getListenPort() { + return listenPort; + } + +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java --- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java Fri Sep 22 10:10:52 2017 -0400 @@ -49,15 +49,15 @@ import org.jboss.byteman.agent.submit.Submit; +import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks; import com.redhat.thermostat.common.portability.ProcessUserInfo; import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; -import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks; import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.jvm.overview.agent.model.VmId; import com.redhat.thermostat.shared.config.CommonPaths; -import com.redhat.thermostat.storage.core.VmId; import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; -import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus; /** * Manages attaching of the byteman agent as well as adding @@ -65,18 +65,18 @@ * */ class BytemanAgentAttachManager { - + private static final String BYTEMAN_PLUGIN_DIR = System.getProperty("thermostat.plugin", "vm-byteman"); private static final String BYTEMAN_PLUGIN_LIBS_DIR = BYTEMAN_PLUGIN_DIR + File.separator + "plugin-libs"; private static final String BYTEMAN_INSTALL_HOME = BYTEMAN_PLUGIN_LIBS_DIR + File.separator + "byteman-install"; private static final String BYTEMAN_HELPER_DIR = BYTEMAN_PLUGIN_LIBS_DIR + File.separator + "thermostat-helper"; private static final String BYTEMAN_HOME_PROPERTY = "org.jboss.byteman.home"; private static final Logger logger = LoggingUtils.getLogger(BytemanAgentAttachManager.class); - + // package-private for testing static final String THERMOSTAT_HELPER_SOCKET_NAME_PROPERTY = "org.jboss.byteman.thermostat.socketName"; static List helperJars; - + private final SubmitHelper submit; private final FileSystemUtils fsUtils; private BytemanAttacher attacher; @@ -89,7 +89,7 @@ this.submit = new SubmitHelper(); this.fsUtils = new FileSystemUtils(); } - + // for testing only BytemanAgentAttachManager(BytemanAttacher attacher, IPCEndpointsManager ipcManager, VmBytemanDAO vmBytemanDao, SubmitHelper submit, WriterID writerId, ProcessUserInfoBuilder userInfoBuilder, FileSystemUtils fsUtils) { @@ -101,7 +101,7 @@ this.userInfoBuilder = userInfoBuilder; this.fsUtils = fsUtils; } - + VmBytemanStatus attachBytemanToVm(VmId vmId, int vmPid) { logger.fine("Attaching byteman agent to VM '" + vmPid + "'"); // Fail early if we can't determine process owner @@ -125,11 +125,11 @@ VmBytemanStatus status = new VmBytemanStatus(writerId.getWriterID()); status.setListenPort(info.getAgentListenPort()); status.setTimeStamp(System.currentTimeMillis()); - status.setVmId(vmId.get()); - vmBytemanDao.addOrReplaceBytemanStatus(status); + status.setJvmId(vmId.get()); + vmBytemanDao.addBytemanStatus(status); return status; } - + private UserPrincipal getUserPrincipalForPid(int vmPid) { UserPrincipal principal = null; ProcessUserInfo info = userInfoBuilder.build(vmPid); @@ -170,12 +170,12 @@ private boolean addThermostatHelperJarsToClasspath(BytemanAgentInfo info) { return submit.addJarsToSystemClassLoader(helperJars, info); } - + static List initListOfHelperJars(CommonPaths commonPaths) { File bytemanHelperDir = new File(commonPaths.getSystemPluginRoot(), BYTEMAN_HELPER_DIR); return initListOfHelperJars(bytemanHelperDir); } - + // package private for testing static synchronized List initListOfHelperJars(File helperDir) { if (helperJars == null) { @@ -187,7 +187,7 @@ } return helperJars; } - + static synchronized void setBytemanHomeProperty(CommonPaths commonPaths) { final String bytemanHomePropVal = System.getProperty(BYTEMAN_HOME_PROPERTY); if (bytemanHomePropVal == null) { @@ -197,7 +197,7 @@ System.setProperty(BYTEMAN_HOME_PROPERTY, bytemanHome); } } - + void setAttacher(BytemanAttacher attacher) { this.attacher = attacher; } @@ -222,9 +222,9 @@ void setUserInfoBuilder(ProcessUserInfoBuilder userInfoBuilder) { this.userInfoBuilder = userInfoBuilder; } - + static class SubmitHelper { - + boolean addJarsToSystemClassLoader(List jars, BytemanAgentInfo info) { Submit submit = new Submit(null /* localhost */, info.getAgentListenPort()); try { @@ -236,7 +236,7 @@ return false; } } - + boolean setSystemProperties(Properties properties, BytemanAgentInfo info) { Submit submit = new Submit(null /* localhost */, info.getAgentListenPort()); try { @@ -248,14 +248,14 @@ return false; } } - + } - + static class FileSystemUtils { - + UserPrincipalLookupService getUserPrincipalLookupService() { return FileSystems.getDefault().getUserPrincipalLookupService(); } - + } } diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiver.java --- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiver.java Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiver.java Fri Sep 22 10:10:52 2017 -0400 @@ -48,9 +48,9 @@ import com.redhat.thermostat.agent.ipc.server.IPCMessage; import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.vm.byteman.common.BytemanMetric; -import com.redhat.thermostat.vm.byteman.common.BytemanMetricTypeAdapterFactory; -import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.BytemanMetric; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.internal.typeadapters.BytemanTypeAdapterFactory; class BytemanMetricsReceiver implements ThermostatIPCCallbacks { @@ -63,7 +63,7 @@ this.dao = dao; this.socketId = socketId; this.gson = new GsonBuilder() - .registerTypeAdapterFactory(new BytemanMetricTypeAdapterFactory()) + .registerTypeAdapterFactory(new BytemanTypeAdapterFactory()) .serializeNulls() .disableHtmlEscaping() .create(); @@ -86,7 +86,7 @@ List listOfMetrics = new ArrayList<>(); for (BytemanMetric m: metrics) { m.setAgentId(socketId.getAgentId()); - m.setVmId(socketId.getVmId()); + m.setJvmId(socketId.getVmId()); listOfMetrics.add(m); } return listOfMetrics; diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequest.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,79 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal; + +public class BytemanRequest { + + public static enum RequestAction { + LOAD_RULES(0), + UNLOAD_RULES(1), + ; + + private int actionId; + + private RequestAction(int id) { + this.actionId = id; + } + + public static RequestAction fromIntString(String id) { + int intId; + try { + intId = Integer.parseInt(id); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Unknown action: " + id); + } + switch(intId) { + case(0): return LOAD_RULES; + case(1): return UNLOAD_RULES; + default: + throw new IllegalArgumentException("Unknown action: " + id); + } + } + + int getActionId() { + return actionId; + } + + } + + public static final String VM_PID_PARAM_NAME = "vm-pid"; + public static final String ACTION_PARAM_NAME = "byteman-action"; + public static final String LISTEN_PORT_PARAM_NAME = "listen-port"; + public static final String RULE_PARAM_NAME = "byteman-rule"; + public static final int NOT_ATTACHED_PORT = -1; + +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java --- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java Fri Sep 22 10:10:52 2017 -0400 @@ -44,8 +44,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; -import com.redhat.thermostat.common.portability.ProcessUserInfoBuilderFactory; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Reference; @@ -53,21 +51,22 @@ import org.jboss.byteman.agent.submit.ScriptText; import org.jboss.byteman.agent.submit.Submit; -import com.redhat.thermostat.agent.command.RequestReceiver; import com.redhat.thermostat.agent.ipc.server.AgentIPCService; -import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.commands.agent.receiver.RequestReceiver; +import com.redhat.thermostat.commands.model.AgentRequest; +import com.redhat.thermostat.commands.model.WebSocketResponse; +import com.redhat.thermostat.commands.model.WebSocketResponse.ResponseType; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilderFactory; import com.redhat.thermostat.common.portability.UserNameUtil; -import com.redhat.thermostat.common.command.Request; -import com.redhat.thermostat.common.command.Response; -import com.redhat.thermostat.common.command.Response.ResponseType; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.jvm.overview.agent.model.VmId; import com.redhat.thermostat.shared.config.CommonPaths; -import com.redhat.thermostat.storage.core.VmId; import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; -import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus; -import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest; -import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest.RequestAction; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus; +import com.redhat.thermostat.vm.byteman.agent.internal.BytemanRequest.RequestAction; /** * Receiver class for Byteman action command channel requests. @@ -75,105 +74,109 @@ */ @Component @Service(value = RequestReceiver.class) -@Property(name = "servicename", value = "com.redhat.thermostat.vm.byteman.agent.internal.BytemanRequestReceiver") +@Property(name = "servicename", value = BytemanRequestReceiver.ACTION_NAME) public class BytemanRequestReceiver implements RequestReceiver { - + + public static final String ACTION_NAME = "byteman"; private static final int ILLEGAL_INT_VAL = -1; private static final int ILLEGAL_PORT = -2; private static final Logger logger = LoggingUtils.getLogger(BytemanRequestReceiver.class); - private static final Response ERROR_RESPONSE = new Response(ResponseType.ERROR); - private static final Response OK_RESPONSE = new Response(ResponseType.OK); - + private final BytemanAgentAttachManager attachManager; - + public BytemanRequestReceiver() { this(new BytemanAgentAttachManager()); } - + // package-private for testing BytemanRequestReceiver(BytemanAgentAttachManager attachManager) { this.attachManager = attachManager; } - + @Reference private VmBytemanDAO vmBytemanDao; - + @Reference private WriterID writerId; - + @Reference private CommonPaths commonPaths; - + @Reference private AgentIPCService agentIpcService; - + @Reference private UserNameUtil userNameUtil; - + //////////////////////////////////////////////// // methods used by DS //////////////////////////////////////////////// - + protected void bindWriterId(WriterID writerId) { this.writerId = writerId; attachManager.setWriterId(writerId); } - + protected void unbindWriterId(WriterID writerId) { this.writerId = null; attachManager.setWriterId(null); } - + protected void bindVmBytemanDao(VmBytemanDAO dao) { this.vmBytemanDao = dao; attachManager.setVmBytemanDao(dao); } - + protected void unbindVmBytemanDao(VmBytemanDAO dao) { this.vmBytemanDao = null; attachManager.setVmBytemanDao(null); } - + protected void bindCommonPaths(CommonPaths paths) { attachManager.setPaths(paths); } - + protected void unbindCommonPaths(CommonPaths paths) { // helper jars don't strictly need unsetting so we don't // call setPaths(null) } - + protected void bindAgentIpcService(AgentIPCService ipcService) { IPCEndpointsManager ipcEndpointsManager = new IPCEndpointsManager(ipcService); attachManager.setIpcManager(ipcEndpointsManager); BytemanAttacher bmAttacher = new BytemanAttacher(ipcService); attachManager.setAttacher(bmAttacher); } - + protected void unbindAgentIpcService(AgentIPCService ipcService) { attachManager.setIpcManager(null); attachManager.setAttacher(null); } - + protected void bindUserNameUtil(UserNameUtil userNameUtil) { ProcessUserInfoBuilder userInfoBuilder = ProcessUserInfoBuilderFactory.createBuilder(new ProcDataSource(), userNameUtil); attachManager.setUserInfoBuilder(userInfoBuilder); } - + protected void unbindUserNameUtil(UserNameUtil userNameUtil) { attachManager.setUserInfoBuilder(null); } - + //////////////////////////////////////////////// // end methods used by DS //////////////////////////////////////////////// - + @Override - public Response receive(Request request) { - String vmId = request.getParameter(BytemanRequest.VM_ID_PARAM_NAME); - String actionStr = request.getParameter(BytemanRequest.ACTION_PARAM_NAME); - String portStr = request.getParameter(BytemanRequest.LISTEN_PORT_PARAM_NAME); - String vmPidStr = request.getParameter(BytemanRequest.VM_PID_PARAM_NAME); + public WebSocketResponse receive(AgentRequest request) { + // Sanity check. We should never get requests outside our action domain. + if (!ACTION_NAME.equals(request.getAction())) { + logger.severe("Received action '" + request.getAction() + "' for receiver '" + ACTION_NAME + "'"); + return new WebSocketResponse(request.getSequenceId(), ResponseType.ERROR); + } + String vmId = request.getJvmId(); + String actionStr = request.getParam(BytemanRequest.ACTION_PARAM_NAME); + String portStr = request.getParam(BytemanRequest.LISTEN_PORT_PARAM_NAME); + String vmPidStr = request.getParam(BytemanRequest.VM_PID_PARAM_NAME); RequestAction action; int vmPid; int port; @@ -181,35 +184,35 @@ action = RequestAction.fromIntString(actionStr); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Illegal action received", e); - return ERROR_RESPONSE; + return error(request.getSequenceId()); } if ((vmPid = tryParseInt(vmPidStr, "VM pid not a number!", ILLEGAL_INT_VAL)) == ILLEGAL_INT_VAL) { - return ERROR_RESPONSE; + return error(request.getSequenceId()); } if ((port = tryParseInt(portStr, "Listen port not an integer!", ILLEGAL_PORT)) == ILLEGAL_PORT) { - return ERROR_RESPONSE; + return error(request.getSequenceId()); } if (!isPortValid(port)) { logger.warning("Listen port is invalid. Got value '" + port + "'"); - return ERROR_RESPONSE; + return error(request.getSequenceId()); } logger.fine("Processing request for vmId: " + vmId + ", pid: " + vmPid + ", Action: " + action + ", port: " + portStr); - Response response = null; + WebSocketResponse response; switch(action) { case LOAD_RULES: - String rule = request.getParameter(BytemanRequest.RULE_PARAM_NAME); - response = attachAndLoadRules(port, new VmId(vmId), vmPid, rule); + String rule = request.getParam(BytemanRequest.RULE_PARAM_NAME); + response = attachAndLoadRules(port, new VmId(vmId), vmPid, rule, request.getSequenceId()); break; case UNLOAD_RULES: - response = unloadRules(port, new VmId(vmId)); + response = unloadRules(port, new VmId(vmId), request.getSequenceId()); break; default: logger.warning("Unknown action: " + action); - return ERROR_RESPONSE; + return error(request.getSequenceId()); } return response; } - + private boolean isPortValid(int port) { if (port <= 0) { // only agent not attached is a valid but negative value @@ -227,15 +230,15 @@ } } - private Response attachAndLoadRules(int listenPort, VmId vmId, int vmPid, String bytemanRules) { + private WebSocketResponse attachAndLoadRules(int listenPort, VmId vmId, int vmPid, String bytemanRules, long sequenceId) { int actualListenPort = attachAgentIfRequired(listenPort, vmId, vmPid); if (actualListenPort == BytemanRequest.NOT_ATTACHED_PORT) { logger.log(Level.WARNING, "Failed to attach byteman agent. Cannot load rules."); - return ERROR_RESPONSE; + return error(sequenceId); } - return loadRules(actualListenPort, vmId, bytemanRules); + return loadRules(actualListenPort, vmId, bytemanRules, sequenceId); } - + private int attachAgentIfRequired(int listenPort, VmId vmId, int vmPid) { if (isAgentAttached(listenPort)) { return listenPort; @@ -247,14 +250,14 @@ } return actualListenPort; } - + private boolean isAgentAttached(int listenPort) { // if we come here with a negative port value we know the agent has not // yet been attached. return listenPort != BytemanRequest.NOT_ATTACHED_PORT; } - private Response loadRules(int listenPort, VmId vmId, String bytemanRules) { + private WebSocketResponse loadRules(int listenPort, VmId vmId, String bytemanRules, final long sequence) { Submit submit = getSubmit(listenPort); try { List existingScripts = submit.getAllScripts(); @@ -269,39 +272,48 @@ status.setListenPort(listenPort); status.setRule(bytemanRules); status.setTimeStamp(System.currentTimeMillis()); - status.setVmId(vmId.get()); - vmBytemanDao.addOrReplaceBytemanStatus(status); - return OK_RESPONSE; + status.setJvmId(vmId.get()); + vmBytemanDao.addBytemanStatus(status); + return ok(sequence); } catch (Exception e) { logger.log(Level.WARNING, "Failed to submit byteman rules", e); - return ERROR_RESPONSE; + return error(sequence); } } - private Response unloadRules(int listenPort, VmId vmId) { + private WebSocketResponse unloadRules(int listenPort, VmId vmId, long sequence) { Submit submit = getSubmit(listenPort); try { List list = submit.getAllScripts(); // Avoid no scripts to delete errors if (!list.isEmpty()) { - submit.deleteAllRules(); + String deleteAllResult = submit.deleteAllRules(); + logger.info("Removed all byteman rules for VM with id '" + vmId.get() + "' with result: " + deleteAllResult); // update the corresponding status in storage VmBytemanStatus newStatus = new VmBytemanStatus(writerId.getWriterID()); newStatus.setListenPort(listenPort); newStatus.setRule(null); newStatus.setTimeStamp(System.currentTimeMillis()); - newStatus.setVmId(vmId.get()); - vmBytemanDao.addOrReplaceBytemanStatus(newStatus); + newStatus.setJvmId(vmId.get()); + vmBytemanDao.addBytemanStatus(newStatus); } - return OK_RESPONSE; + return ok(sequence); } catch (Exception e) { logger.log(Level.WARNING, "Failed to delete rules", e); - return ERROR_RESPONSE; + return error(sequence); } } + private WebSocketResponse error(long sequence) { + return new WebSocketResponse(sequence, ResponseType.ERROR); + } + + private WebSocketResponse ok(long sequence) { + return new WebSocketResponse(sequence, ResponseType.OK); + } + protected Submit getSubmit(int listenPort) { return new Submit(null /* localhost */, listenPort); } - + } diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanDAOImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanDAOImpl.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,110 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.Service; + +import com.google.gson.Gson; +import com.redhat.thermostat.agent.http.HttpRequestService; +import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource; +import com.redhat.thermostat.common.plugin.PluginConfiguration; +import com.redhat.thermostat.common.plugin.SystemID; +import com.redhat.thermostat.vm.byteman.agent.BytemanMetric; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus; +import com.redhat.thermostat.vm.byteman.agent.internal.typeadapters.GsonCreator; + +@Component +@Service(value = VmBytemanDAO.class) +public class VmBytemanDAOImpl implements VmBytemanDAO { + + private static final String PLUGIN_ID = "vm-byteman"; + + private final ConfigurationCreator configCreator; + private final GsonCreator gsonCreator; + + @Reference + private HttpRequestService httpRequestService; + @Reference + private ConfigurationInfoSource configInfoSource; + @Reference + private SystemID systemId; + + private VmBytemanMetricsStore metricsStore; + + private VmBytemanStatusStore statusStore; + + public VmBytemanDAOImpl() { + this(new ConfigurationCreator(), new GsonCreator()); + } + + VmBytemanDAOImpl(ConfigurationCreator configCreator, GsonCreator creator) { + this.configCreator = configCreator; + this.gsonCreator = creator; + } + + @Activate + private void activate() { + PluginConfiguration config = configCreator.create(configInfoSource); + Gson gson = gsonCreator.create(); + metricsStore = new VmBytemanMetricsStore(httpRequestService, config, systemId, gson); + statusStore = new VmBytemanStatusStore(httpRequestService, config, systemId, gson); + } + + @Override + public void addMetric(final BytemanMetric metric) { + metricsStore.put(metric); + } + + @Override + public void addBytemanStatus(final VmBytemanStatus status) { + statusStore.put(status); + } + + // For Testing purposes + static class ConfigurationCreator { + + PluginConfiguration create(ConfigurationInfoSource source) { + return new PluginConfiguration(source, PLUGIN_ID); + } + + } + +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanMetricsStore.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanMetricsStore.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,98 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal; + +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Logger; + +import com.google.gson.Gson; +import com.redhat.thermostat.agent.http.HttpRequestService; +import com.redhat.thermostat.common.plugin.PluginConfiguration; +import com.redhat.thermostat.common.plugin.PluginDAOBase; +import com.redhat.thermostat.common.plugin.SystemID; +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.vm.byteman.agent.BytemanMetric; + +class VmBytemanMetricsStore extends PluginDAOBase { + + private static final String METRICS_PATH = "metrics"; + private static final Logger LOGGER = LoggingUtils.getLogger(VmBytemanMetricsStore.class); + private final HttpRequestService httpRequestService; + private final PluginConfiguration pluginConfig; + private final SystemID systemId; + private final Gson gson; + + VmBytemanMetricsStore(HttpRequestService httpRequestService, + PluginConfiguration pluginConfig, + SystemID systemId, + Gson gson) { + this.httpRequestService = httpRequestService; + this.pluginConfig = pluginConfig; + this.systemId = systemId; + this.gson = gson; + } + + @Override + protected String toJsonString(BytemanMetric obj) throws IOException { + List bytemanMetrics = Arrays.asList(obj); + return gson.toJson(bytemanMetrics); + } + + @Override + protected HttpRequestService getHttpRequestService() { + return httpRequestService; + } + + @Override + protected PluginConfiguration getConfig() { + return pluginConfig; + } + + @Override + protected URI getPostURI(URI basepath, BytemanMetric obj) { + return basepath.resolve(METRICS_PATH + "/systems/" + systemId.getSystemID() + "/jvms/" + obj.getJvmId()); + } + + @Override + protected Logger getLogger() { + return LOGGER; + } + +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanStatusStore.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanStatusStore.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,99 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal; + +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.google.gson.Gson; +import com.redhat.thermostat.agent.http.HttpRequestService; +import com.redhat.thermostat.common.plugin.PluginConfiguration; +import com.redhat.thermostat.common.plugin.PluginDAOBase; +import com.redhat.thermostat.common.plugin.SystemID; +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus; + +class VmBytemanStatusStore extends PluginDAOBase { + + private static final String STATUS_PATH = "status"; + private static final Logger LOGGER = LoggingUtils.getLogger(VmBytemanStatusStore.class); + private final HttpRequestService httpRequestService; + private final PluginConfiguration pluginConfig; + private final SystemID systemId; + private final Gson gson; + + VmBytemanStatusStore(HttpRequestService httpRequestService, + PluginConfiguration pluginConfig, + SystemID systemId, + Gson gson) { + this.httpRequestService = httpRequestService; + this.pluginConfig = pluginConfig; + this.systemId = systemId; + this.gson = gson; + } + + @Override + protected String toJsonString(VmBytemanStatus obj) throws IOException { + List vmBytemanStatuses = Arrays.asList(obj); + return gson.toJson(vmBytemanStatuses); + } + + @Override + protected HttpRequestService getHttpRequestService() { + return httpRequestService; + } + + @Override + protected PluginConfiguration getConfig() { + return pluginConfig; + } + + @Override + protected URI getPostURI(URI basepath, VmBytemanStatus obj) { + return basepath.resolve(STATUS_PATH + "/systems/" + systemId.getSystemID() + "/jvms/" + obj.getJvmId()); + } + + @Override + protected Logger getLogger() { + return LOGGER; + } + +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/BytemanMetricTypeAdapter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/BytemanMetricTypeAdapter.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,138 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal.typeadapters; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import com.redhat.thermostat.vm.byteman.agent.BytemanMetric; + +class BytemanMetricTypeAdapter extends TypeAdapter { + + private static final String TYPE_LONG = "$numberLong"; + private static final String VM_ID = "jvmId"; + private static final String AGENT_ID = "agentId"; + private static final String MARKER = "marker"; + private static final String JSON_PAYLOAD = "payload"; + private static final String TIMESTAMP = "timeStamp"; + + private final Gson gson; + + BytemanMetricTypeAdapter(Gson gson) { + this.gson = gson; + } + + @Override + public BytemanMetric read(JsonReader reader) throws IOException { + // handle null + if (reader.peek() == JsonToken.NULL) { + reader.nextNull(); + return null; + } + + reader.beginObject(); + BytemanMetric metric = parseMetric(reader); + reader.endObject(); + return metric; + } + + @Override + public void write(JsonWriter out, BytemanMetric metric) throws IOException { + out.beginObject(); + out.name(AGENT_ID); + out.value(metric.getAgentId()); + out.name(VM_ID); + out.value(metric.getJvmId()); + out.name(MARKER); + out.value(metric.getMarker()); + out.name(JSON_PAYLOAD); + out.value(metric.getDataAsJson()); + out.name(TIMESTAMP); + writeLong(out, metric.getTimeStamp()); + out.endObject(); + } + + private void writeLong(JsonWriter out, long value) throws IOException { + // Write MongoDB representation of a Long + out.beginObject(); + out.name(TYPE_LONG); + out.value(String.valueOf(value)); + out.endObject(); + } + + @SuppressWarnings("unchecked") + private BytemanMetric parseMetric(JsonReader reader) throws IOException { + Map values = new HashMap<>(); + while (reader.hasNext()) { + String name = reader.nextName(); + switch(name) { + case BytemanMetric.MARKER_NAME: + values.put(BytemanMetric.MARKER_NAME, reader.nextString()); + break; + case BytemanMetric.TIMESTAMP_NAME: + values.put(BytemanMetric.TIMESTAMP_NAME, Long.valueOf(reader.nextString())); + break; + case BytemanMetric.DATA_NAME: + Map data = getDataValues(reader); + values.put(BytemanMetric.DATA_NAME, data); + break; + default: + throw new IllegalStateException("Unknown name: '" + name + "'"); + } + } + BytemanMetric metric = new BytemanMetric(); + metric.setMarker((String)values.get(BytemanMetric.MARKER_NAME)); + metric.setTimeStamp((Long)values.get(BytemanMetric.TIMESTAMP_NAME)); + metric.setData(mapToJson((Map)values.get(BytemanMetric.DATA_NAME))); + return metric; + } + + private String mapToJson(Map map) { + return gson.toJson(map, HashMap.class); + } + + private Map getDataValues(JsonReader reader) throws IOException { + return gson.fromJson(reader, HashMap.class); + } + +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/BytemanTypeAdapterFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/BytemanTypeAdapterFactory.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,63 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal.typeadapters; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.redhat.thermostat.vm.byteman.agent.BytemanMetric; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus; + +public class BytemanTypeAdapterFactory implements TypeAdapterFactory { + + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + Class rawType = type.getRawType(); + if (rawType == BytemanMetric.class) { + @SuppressWarnings("unchecked") + TypeAdapter ta = (TypeAdapter)new BytemanMetricTypeAdapter(gson); + return ta; + } else if (rawType == VmBytemanStatus.class) { + @SuppressWarnings("unchecked") + TypeAdapter ta = (TypeAdapter)new VmBytemanStatusTypeAdapter(); + return ta; + } + return null; + } + +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/GsonCreator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/GsonCreator.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,50 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal.typeadapters; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class GsonCreator { + + public Gson create() { + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeAdapterFactory(new BytemanTypeAdapterFactory()); + builder.serializeNulls(); + return builder.create(); + } +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/VmBytemanStatusTypeAdapter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/VmBytemanStatusTypeAdapter.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,83 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal.typeadapters; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus; + +import java.io.IOException; + +public class VmBytemanStatusTypeAdapter extends TypeAdapter { + + private static final String TYPE_LONG = "$numberLong"; + private static final String VM_ID = "jvmId"; + private static final String AGENT_ID = "agentId"; + private static final String TIMESTAMP = "timeStamp"; + private static final String RULE = "rule"; + private static final String LISTEN_PORT = "listenPort"; + + @Override + public VmBytemanStatus read(JsonReader in) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void write(JsonWriter out, VmBytemanStatus status) throws IOException { + out.beginObject(); + out.name(AGENT_ID); + out.value(status.getAgentId()); + out.name(VM_ID); + out.value(status.getJvmId()); + out.name(TIMESTAMP); + writeLong(out, status.getTimeStamp()); + out.name(RULE); + out.value(status.getRule()); + out.name(LISTEN_PORT); + out.value(status.getListenPort()); + out.endObject(); + } + + private void writeLong(JsonWriter out, long value) throws IOException { + // Write MongoDB representation of a Long + out.beginObject(); + out.name(TYPE_LONG); + out.value(String.valueOf(value)); + out.endObject(); + } +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java --- a/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java Fri Sep 22 10:10:52 2017 -0400 @@ -63,26 +63,26 @@ import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks; +import com.redhat.thermostat.common.portability.ProcessChecker; import com.redhat.thermostat.common.portability.ProcessUserInfo; import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; -import com.redhat.thermostat.common.portability.ProcessChecker; -import com.redhat.thermostat.storage.core.VmId; +import com.redhat.thermostat.jvm.overview.agent.model.VmId; import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus; import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAgentAttachManager.FileSystemUtils; import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAgentAttachManager.SubmitHelper; import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.BtmInstallHelper; -import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; -import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus; public class BytemanAgentAttachManagerTest { - + private static final VmId SOME_VM_ID = new VmId("some-vm-id"); private static final int SOME_VM_PID = 99910; private static final String SOME_AGENT_ID = "some-agent-id"; private static final int SOME_UID = 1111; private static final String SOME_USERNAME = "someUser"; private static final BytemanAgentInfo SOME_SUCCESS_BYTEMAN_INFO = new BytemanAgentInfo(SOME_VM_PID, 3344, null, SOME_VM_ID.get(), SOME_AGENT_ID, false, false); - + private BytemanAgentAttachManager manager; private IPCEndpointsManager ipcManager; private VmBytemanDAO vmBytemanDao; @@ -90,7 +90,7 @@ private BytemanAttacher bytemanAttacher; private ProcessUserInfoBuilder userInfoBuilder; private UserPrincipalLookupService lookup; - + @Before public void setup() throws IOException { ipcManager = mock(IPCEndpointsManager.class); @@ -101,7 +101,7 @@ when(writerId.getWriterID()).thenReturn(SOME_AGENT_ID); userInfoBuilder = mock(ProcessUserInfoBuilder.class); FileSystemUtils fsUtils = mock(FileSystemUtils.class); - + ProcessUserInfo info = new ProcessUserInfo(SOME_UID, SOME_USERNAME); when(userInfoBuilder.build(SOME_VM_PID)).thenReturn(info); lookup = mock(UserPrincipalLookupService.class); @@ -110,7 +110,7 @@ when(lookup.lookupPrincipalByName(SOME_USERNAME)).thenReturn(owner); manager = new BytemanAgentAttachManager(bytemanAttacher, ipcManager, vmBytemanDao, submit, writerId, userInfoBuilder, fsUtils); } - + @After public void tearDown() { BytemanAgentAttachManager.helperJars = null; @@ -125,42 +125,42 @@ int listenPort = 9881; BytemanAgentInfo bytemanAgentInfo = new BytemanAgentInfo(vmPid, listenPort, null, workingVmId, agentId, false, false); when(bytemanAttacher.attach(workingVmId, vmPid, agentId)).thenReturn(bytemanAgentInfo); - + // mock that installing of helper jars works when(submit.addJarsToSystemClassLoader(any(List.class), any(BytemanAgentInfo.class))).thenReturn(true); - + ProcessUserInfo info = new ProcessUserInfo(5000, "testUser"); when(userInfoBuilder.build(vmPid)).thenReturn(info); UserPrincipal owner = mock(UserPrincipal.class); when(lookup.lookupPrincipalByName("testUser")).thenReturn(owner); - + VmId vmId = new VmId(workingVmId); WriterID writerId = mock(WriterID.class); when(writerId.getWriterID()).thenReturn(agentId); manager.setWriterId(writerId); VmBytemanStatus bytemanStatus = manager.attachBytemanToVm(vmId, vmPid); VmSocketIdentifier socketId = new VmSocketIdentifier(workingVmId, vmPid, agentId); - + // IPC endpoint must be started verify(ipcManager).startIPCEndpoint(eq(socketId), isA(BytemanMetricsReceiver.class), eq(owner)); - + // Status should have been updated/inserted ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(VmBytemanStatus.class); - verify(vmBytemanDao).addOrReplaceBytemanStatus(statusCaptor.capture()); + verify(vmBytemanDao).addBytemanStatus(statusCaptor.capture()); VmBytemanStatus capturedStatus = statusCaptor.getValue(); assertNotNull(capturedStatus); - assertEquals(workingVmId, capturedStatus.getVmId()); + assertEquals(workingVmId, capturedStatus.getJvmId()); assertEquals(agentId, capturedStatus.getAgentId()); assertEquals(listenPort, capturedStatus.getListenPort()); assertNull(capturedStatus.getRule()); assertTrue(capturedStatus.getTimeStamp() > 0); - + // Helper jars must have been added to classpath verify(submit).addJarsToSystemClassLoader(eq((List)null), eq(bytemanAgentInfo)); - + assertEquals(listenPort, bytemanStatus.getListenPort()); } - + @SuppressWarnings("unchecked") @Test public void canUseOldAttachedAgentStartIPCandAddsStatus() throws IOException { @@ -170,70 +170,70 @@ int listenPort = 9881; BytemanAgentInfo bytemanAgentInfo = new BytemanAgentInfo(vmPid, listenPort, null, workingVmId, agentId, false, true); when(bytemanAttacher.attach(workingVmId, vmPid, agentId)).thenReturn(bytemanAgentInfo); - + // mock setting system properties' success when(submit.setSystemProperties(any(Properties.class), any(BytemanAgentInfo.class))).thenReturn(true); - + ProcessUserInfo info = new ProcessUserInfo(5000, "testUser"); when(userInfoBuilder.build(vmPid)).thenReturn(info); UserPrincipal owner = mock(UserPrincipal.class); when(lookup.lookupPrincipalByName("testUser")).thenReturn(owner); - + VmId vmId = new VmId(workingVmId); WriterID writerId = mock(WriterID.class); when(writerId.getWriterID()).thenReturn(agentId); manager.setWriterId(writerId); VmBytemanStatus bytemanStatus = manager.attachBytemanToVm(vmId, vmPid); VmSocketIdentifier socketId = new VmSocketIdentifier(workingVmId, vmPid, agentId); - + // IPC endpoint must be started verify(ipcManager).startIPCEndpoint(eq(socketId), isA(BytemanMetricsReceiver.class), eq(owner)); - + // Status should have been updated/inserted ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(VmBytemanStatus.class); - verify(vmBytemanDao).addOrReplaceBytemanStatus(statusCaptor.capture()); + verify(vmBytemanDao).addBytemanStatus(statusCaptor.capture()); VmBytemanStatus capturedStatus = statusCaptor.getValue(); assertNotNull(capturedStatus); - assertEquals(workingVmId, capturedStatus.getVmId()); + assertEquals(workingVmId, capturedStatus.getJvmId()); assertEquals(agentId, capturedStatus.getAgentId()); assertEquals(listenPort, capturedStatus.getListenPort()); assertNull(capturedStatus.getRule()); assertTrue(capturedStatus.getTimeStamp() > 0); - + // Helper jars must not have been added again to classpath verify(submit, times(0)).addJarsToSystemClassLoader(any(List.class), any(BytemanAgentInfo.class)); - + // Verify properties got set appropriately ArgumentCaptor propsCaptor = ArgumentCaptor.forClass(Properties.class); verify(submit).setSystemProperties(propsCaptor.capture(), eq(bytemanAgentInfo)); Properties props = propsCaptor.getValue(); String propVal = props.getProperty(BytemanAgentAttachManager.THERMOSTAT_HELPER_SOCKET_NAME_PROPERTY); assertEquals(socketId.getName(), propVal); - + assertEquals(listenPort, bytemanStatus.getListenPort()); } - + @Test public void usernameFailureDoesNotAttach() throws IOException { ProcessUserInfo info = new ProcessUserInfo(SOME_UID, null); when(userInfoBuilder.build(SOME_VM_PID)).thenReturn(info); - + VmBytemanStatus status = manager.attachBytemanToVm(SOME_VM_ID, SOME_VM_PID); verify(bytemanAttacher, never()).attach(any(String.class), any(int.class), any(String.class)); verify(ipcManager, never()).startIPCEndpoint(any(VmSocketIdentifier.class), any(ThermostatIPCCallbacks.class), any(UserPrincipal.class)); assertNull(status); } - + @Test public void userPrincipalExceptionDoesNotAttach() throws IOException { when(lookup.lookupPrincipalByName(SOME_USERNAME)).thenThrow(new IOException("TEST")); - + VmBytemanStatus status = manager.attachBytemanToVm(SOME_VM_ID, SOME_VM_PID); verify(bytemanAttacher, never()).attach(any(String.class), any(int.class), any(String.class)); verify(ipcManager, never()).startIPCEndpoint(any(VmSocketIdentifier.class), any(ThermostatIPCCallbacks.class), any(UserPrincipal.class)); assertNull(status); } - + @Test public void failureToAttachDoesNotStartIPC() throws Exception { BytemanAttacher failAttacher = getFailureAttacher(); @@ -248,21 +248,21 @@ BytemanAttacher failAttacher = getFailureAttacher(); manager.setAttacher(failAttacher); VmBytemanStatus status = manager.attachBytemanToVm(SOME_VM_ID, SOME_VM_PID); - verify(vmBytemanDao, never()).addOrReplaceBytemanStatus(any(VmBytemanStatus.class)); + verify(vmBytemanDao, never()).addBytemanStatus(any(VmBytemanStatus.class)); assertNull(status); } - + @SuppressWarnings("unchecked") @Test public void successfulAttachAddsHelperJars() { // mock that installing of helper jars works when(submit.addJarsToSystemClassLoader(any(List.class), any(BytemanAgentInfo.class))).thenReturn(true); - + when(bytemanAttacher.attach(SOME_VM_ID.get(), SOME_VM_PID, SOME_AGENT_ID)).thenReturn(SOME_SUCCESS_BYTEMAN_INFO); manager.attachBytemanToVm(SOME_VM_ID, SOME_VM_PID); verify(submit).addJarsToSystemClassLoader(any(List.class), any(BytemanAgentInfo.class)); } - + @Test public void canGetListOfJarsForBytemanHelper() { String parent = "/foo"; @@ -278,7 +278,7 @@ assertEquals("/foo/test-file" + i + ".jar", jars.get(i)); } } - + @SuppressWarnings("unchecked") private BytemanAttacher getFailureAttacher() throws Exception { AgentIPCService ipcService = mock(AgentIPCService.class); diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiverTest.java --- a/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiverTest.java Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiverTest.java Fri Sep 22 10:10:52 2017 -0400 @@ -53,9 +53,9 @@ import org.mockito.ArgumentCaptor; import com.redhat.thermostat.agent.ipc.server.IPCMessage; -import com.redhat.thermostat.vm.byteman.common.BytemanMetric; -import com.redhat.thermostat.vm.byteman.common.JsonHelper; -import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.BytemanMetric; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.internal.typeadapter.JsonHelper; public class BytemanMetricsReceiverTest { @@ -74,7 +74,7 @@ receiver.messageReceived(message); verify(dao, times(3)).addMetric(metricsCaptor.capture()); List metrics = metricsCaptor.getAllValues(); - assertEquals("vm-id", metrics.get(0).getVmId()); + assertEquals("vm-id", metrics.get(0).getJvmId()); assertEquals("agent-id", metrics.get(2).getAgentId()); assertTrue(metrics.get(1).getTimeStamp() > 0); assertEquals("baz0", metrics.get(0).getMarker()); diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java --- a/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java Fri Sep 22 10:10:52 2017 -0400 @@ -46,10 +46,11 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.net.InetSocketAddress; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; import org.jboss.byteman.agent.submit.ScriptText; import org.jboss.byteman.agent.submit.Submit; @@ -58,40 +59,40 @@ import org.mockito.ArgumentCaptor; import com.redhat.thermostat.agent.ipc.server.AgentIPCService; -import com.redhat.thermostat.common.command.Request; -import com.redhat.thermostat.common.command.Request.RequestType; -import com.redhat.thermostat.common.command.Response; -import com.redhat.thermostat.common.command.Response.ResponseType; +import com.redhat.thermostat.commands.model.AgentRequest; +import com.redhat.thermostat.commands.model.WebSocketResponse; +import com.redhat.thermostat.commands.model.WebSocketResponse.ResponseType; +import com.redhat.thermostat.jvm.overview.agent.model.VmId; import com.redhat.thermostat.shared.config.CommonPaths; -import com.redhat.thermostat.storage.core.VmId; import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.storage.model.VmInfo; -import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; -import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus; -import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest; -import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest.RequestAction; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus; +import com.redhat.thermostat.vm.byteman.agent.internal.BytemanRequest.RequestAction; public class BytemanRequestReceiverTest { - + + private static final String SYSTEM_ID = "some-system-id"; private static final String SOME_VM_ID = "some-vm-id"; private static final int SOME_LISTENPORT_BTM_AGENT_ATTACHED = 333; private static final String SOME_WRITER_ID = "some-writer-id"; private static final String SOME_RULE = "some-rule"; - private VmInfo someVmInfo; - + private static final String BYTEMAN_ACTION = "byteman"; + private static final int UNSET_JVM_PID = -99; + private static final String NO_RULE = null; + private long sequence; + @Before public void setup() { - someVmInfo = mock(VmInfo.class); - when(someVmInfo.getVmId()).thenReturn(SOME_VM_ID); + sequence = (long)(1000 * Math.random()); } - + @Test public void testLoadRulesAgentAttached() throws Exception { Submit submit = mock(Submit.class); doBasicLoadRulesTestBtmAgentAttached(submit); verify(submit, never()).deleteAllRules(); } - + @Test public void testLoadRulesAgentAttachedWithRulesExisting() throws Exception { Submit submit = mock(Submit.class); @@ -99,17 +100,29 @@ doBasicLoadRulesTestBtmAgentAttached(submit); verify(submit).deleteAllRules(); } - + @Test public void testUnLoadRulesWithNoExistingRules() throws Exception { Submit submit = mock(Submit.class); when(submit.getAllScripts()).thenReturn(Collections.emptyList()); BytemanRequestReceiver receiver = createReceiver(submit, null, null); - Response response = receiver.receive(BytemanRequest.create(mock(InetSocketAddress.class), someVmInfo, RequestAction.UNLOAD_RULES, -1)); - assertEquals(ResponseType.OK, response.getType()); + int someListenPort = 29320; + int someJvmPid = 3280; + WebSocketResponse response = receiver.receive(createRequest(RequestAction.UNLOAD_RULES, someListenPort, NO_RULE, someJvmPid)); + assertEquals(ResponseType.OK, response.getResponseType()); + assertEquals(sequence, response.getSequenceId()); verify(submit, never()).deleteAllRules(); } - + + @Test + public void testReceiveBadAction() throws Exception { + AgentRequest request = new AgentRequest(sequence, "wrong-action", SYSTEM_ID, SOME_VM_ID, new TreeMap()); + BytemanRequestReceiver receiver = createReceiver(mock(Submit.class), mock(WriterID.class), mock(VmBytemanDAO.class)); + WebSocketResponse response = receiver.receive(request); + assertEquals(ResponseType.ERROR, response.getResponseType()); + assertEquals(sequence, response.getSequenceId()); + } + @Test public void testUnLoadRulesWithExistingRules() throws Exception { Submit submit = mock(Submit.class); @@ -118,30 +131,34 @@ String someAgentId = "some-agent-id"; String someVmId = "some-vm-id"; int someListenPort = 3333; + int someJvmPid = 2321; VmBytemanDAO bytemanDao = mock(VmBytemanDAO.class); when(writerId.getWriterID()).thenReturn(someAgentId); BytemanRequestReceiver receiver = createReceiver(submit, writerId, bytemanDao); ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(VmBytemanStatus.class); - Response response = receiver.receive(BytemanRequest.create(mock(InetSocketAddress.class), someVmInfo, RequestAction.UNLOAD_RULES, someListenPort)); - assertEquals(ResponseType.OK, response.getType()); + WebSocketResponse response = receiver.receive(createRequest(RequestAction.UNLOAD_RULES, someListenPort, NO_RULE, someJvmPid)); + assertEquals(ResponseType.OK, response.getResponseType()); + assertEquals(sequence, response.getSequenceId()); verify(submit).deleteAllRules(); - verify(bytemanDao).addOrReplaceBytemanStatus(statusCaptor.capture()); + verify(bytemanDao).addBytemanStatus(statusCaptor.capture()); VmBytemanStatus status = statusCaptor.getValue(); assertEquals(someAgentId, status.getAgentId()); - assertEquals(someVmId, status.getVmId()); + assertEquals(someVmId, status.getJvmId()); assertEquals(someListenPort, status.getListenPort()); assertNull(status.getRule()); } - + @Test public void testReceiveWithBadAction() { - Request badRequest = new Request(RequestType.RESPONSE_EXPECTED, mock(InetSocketAddress.class)); - badRequest.setParameter(BytemanRequest.ACTION_PARAM_NAME, Integer.toString(-1)); + SortedMap paramMap = new TreeMap<>(); + paramMap.put(BytemanRequest.ACTION_PARAM_NAME, Integer.toString(-1)); + AgentRequest badRequest = new AgentRequest(sequence, "byteman", "some-system-id", "jvm-id-foo", paramMap); BytemanRequestReceiver receiver = new BytemanRequestReceiver(); - Response response = receiver.receive(badRequest); - assertEquals(ResponseType.ERROR, response.getType()); + WebSocketResponse response = receiver.receive(badRequest); + assertEquals(ResponseType.ERROR, response.getResponseType()); + assertEquals(sequence, response.getSequenceId()); } - + @SuppressWarnings("unchecked") @Test public void testLoadRuleWithBytemanAgentNotAttached() throws Exception { @@ -155,7 +172,7 @@ WriterID wid = mock(WriterID.class); when(wid.getWriterID()).thenReturn(SOME_WRITER_ID); BytemanRequestReceiver receiver = new BytemanRequestReceiver(attachManager) { - @Override + @Override protected Submit getSubmit(int port) { assertEquals(listenPort, port); return submit; @@ -163,36 +180,35 @@ }; receiver.bindWriterId(wid); receiver.bindVmBytemanDao(bytemanDao); - VmInfo vmInfo = mock(VmInfo.class); - when(vmInfo.getVmId()).thenReturn(SOME_VM_ID); int someVmPid = 3023; - when(vmInfo.getVmPid()).thenReturn(someVmPid); - Request loadRequest = BytemanRequest.create(mock(InetSocketAddress.class), vmInfo, RequestAction.LOAD_RULES, BytemanRequest.NOT_ATTACHED_PORT, SOME_RULE); + AgentRequest loadRequest = createRequest(RequestAction.LOAD_RULES, BytemanRequest.NOT_ATTACHED_PORT, SOME_RULE, someVmPid); receiver.receive(loadRequest); VmId vmId = new VmId(SOME_VM_ID); verify(attachManager).attachBytemanToVm(eq(vmId), eq(someVmPid)); verify(submit).addRulesFromResources(any(List.class)); } - + @Test public void testUnloadRuleIllegalPid() { - VmInfo vmInfoWithBadPid = mock(VmInfo.class); - when(vmInfoWithBadPid.getVmPid()).thenReturn(-1); // bad value - Request loadRequest = BytemanRequest.create(mock(InetSocketAddress.class), vmInfoWithBadPid, RequestAction.UNLOAD_RULES, SOME_LISTENPORT_BTM_AGENT_ATTACHED); + int badJvmPid = -1; + AgentRequest loadRequest = createRequest(RequestAction.UNLOAD_RULES, SOME_LISTENPORT_BTM_AGENT_ATTACHED, NO_RULE, badJvmPid); BytemanRequestReceiver receiver = new BytemanRequestReceiver(); - Response response = receiver.receive(loadRequest); - assertEquals(ResponseType.ERROR, response.getType()); + WebSocketResponse response = receiver.receive(loadRequest); + assertEquals(ResponseType.ERROR, response.getResponseType()); + assertEquals(sequence, response.getSequenceId()); } - + @Test public void testUnloadRuleIllegalPort() { int invalidPort = -3; - Request loadRequest = BytemanRequest.create(mock(InetSocketAddress.class), someVmInfo, RequestAction.UNLOAD_RULES, invalidPort); + int validPid = 2302; + AgentRequest loadRequest = createRequest(RequestAction.UNLOAD_RULES, invalidPort, NO_RULE, validPid); BytemanRequestReceiver receiver = new BytemanRequestReceiver(); - Response response = receiver.receive(loadRequest); - assertEquals(ResponseType.ERROR, response.getType()); + WebSocketResponse response = receiver.receive(loadRequest); + assertEquals(ResponseType.ERROR, response.getResponseType()); + assertEquals(sequence, response.getSequenceId()); } - + @Test public void testBindWriterId() { BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class); @@ -201,7 +217,7 @@ receiver.bindWriterId(wid); verify(attachManager).setWriterId(wid); } - + @Test public void testBindVmBytemanDAO() { BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class); @@ -210,7 +226,7 @@ receiver.bindVmBytemanDao(dao); verify(attachManager).setVmBytemanDao(dao); } - + @Test public void testBindCommonPaths() { BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class); @@ -219,7 +235,7 @@ receiver.bindCommonPaths(paths); verify(attachManager).setPaths(paths); } - + @Test public void testBindAgentIPCService() { BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class); @@ -232,35 +248,51 @@ @SuppressWarnings("unchecked") private void doBasicLoadRulesTestBtmAgentAttached(Submit submit) throws Exception { + int someValidPid = 3090; VmBytemanDAO bytemanDao = mock(VmBytemanDAO.class); WriterID wid = mock(WriterID.class); when(wid.getWriterID()).thenReturn(SOME_WRITER_ID); BytemanRequestReceiver receiver = createReceiver(submit, wid, bytemanDao); ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(VmBytemanStatus.class); - Response response = receiver.receive(BytemanRequest.create(mock(InetSocketAddress.class), someVmInfo, RequestAction.LOAD_RULES, SOME_LISTENPORT_BTM_AGENT_ATTACHED, SOME_RULE)); - verify(bytemanDao).addOrReplaceBytemanStatus(statusCaptor.capture()); + WebSocketResponse response = receiver.receive(createRequest(RequestAction.LOAD_RULES, SOME_LISTENPORT_BTM_AGENT_ATTACHED, SOME_RULE, someValidPid)); + verify(bytemanDao).addBytemanStatus(statusCaptor.capture()); VmBytemanStatus capturedStatus = statusCaptor.getValue(); - assertEquals(SOME_VM_ID, capturedStatus.getVmId()); + assertEquals(SOME_VM_ID, capturedStatus.getJvmId()); assertEquals(SOME_WRITER_ID, capturedStatus.getAgentId()); assertEquals(SOME_RULE, capturedStatus.getRule()); assertEquals(SOME_LISTENPORT_BTM_AGENT_ATTACHED, capturedStatus.getListenPort()); // verify no helper jars get added on rule submission verify(submit, times(0)).addJarsToSystemClassloader(any(List.class)); verify(submit).addRulesFromResources(any(List.class)); - assertEquals(ResponseType.OK, response.getType()); + assertEquals(ResponseType.OK, response.getResponseType()); + assertEquals(sequence, response.getSequenceId()); } private BytemanRequestReceiver createReceiver(final Submit submit, WriterID writerId, VmBytemanDAO dao) { BytemanRequestReceiver receiver = new BytemanRequestReceiver() { - @Override + @Override protected Submit getSubmit(int port) { return submit; } - + }; receiver.bindVmBytemanDao(dao); receiver.bindWriterId(writerId); return receiver; } - + + private AgentRequest createRequest(RequestAction action, int listenPort, String someRule, int jvmPid) { + SortedMap params = new TreeMap<>(); + params.put(BytemanRequest.ACTION_PARAM_NAME, Integer.toString(action.getActionId())); + params.put(BytemanRequest.LISTEN_PORT_PARAM_NAME, Integer.toString(listenPort)); + if (someRule != null) { + params.put(BytemanRequest.RULE_PARAM_NAME, someRule); + } + if (jvmPid != UNSET_JVM_PID) { + params.put(BytemanRequest.VM_PID_PARAM_NAME, Integer.toString(jvmPid)); + } + AgentRequest request = new AgentRequest(sequence, BYTEMAN_ACTION, SYSTEM_ID, SOME_VM_ID, params); + return request; + } + } diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/IPCEndpointsManagerTest.java --- a/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/IPCEndpointsManagerTest.java Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/IPCEndpointsManagerTest.java Fri Sep 22 10:10:52 2017 -0400 @@ -52,7 +52,7 @@ import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks; -import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO; public class IPCEndpointsManagerTest { diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/BytemanMetricTypeAdapterTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/BytemanMetricTypeAdapterTest.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,132 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal.typeadapter; + +import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.redhat.thermostat.vm.byteman.agent.BytemanMetric; +import com.redhat.thermostat.vm.byteman.agent.internal.typeadapters.BytemanTypeAdapterFactory; + +public class BytemanMetricTypeAdapterTest { + + private static final double DELTA = 0.001; + + private Gson gson; + + @Before + public void setup() { + gson = new GsonBuilder() + .registerTypeAdapterFactory(new BytemanTypeAdapterFactory()) + .disableHtmlEscaping() + .serializeNulls() + .create(); + } + + @Test + public void canDeserializeArrayOfMetrics() { + String json = JsonHelper.buildJsonArray(10); + BytemanMetric[] metrics = gson.fromJson(json, BytemanMetric[].class); + assertEquals(10, metrics.length); + for (int i = 0; i < 10; i++) { + assertEquals("baz" + i, metrics[i].getMarker()); + assertEquals(1234567890 + i, metrics[i].getTimeStamp()); + Map dataAsMap = metrics[i].getDataAsMap(); + assertFalse((Boolean)dataAsMap.get("foo4")); + assertEquals("[]", (String)dataAsMap.get("foo5")); + double foo3Val = (double)dataAsMap.get("foo3"); + String foo3Str = String.format("42.%d", i); + double expectedFoo3Val = Double.parseDouble(foo3Str); + assertEquals(expectedFoo3Val, foo3Val, DELTA); + double foo2Val = (double)dataAsMap.get("foo2"); + String foo2Str = String.format("42%d.0", i); + double expectedFoo2Val = Double.parseDouble(foo2Str); + assertEquals(expectedFoo2Val, foo2Val, DELTA); + assertEquals("ba\"r1", (String)dataAsMap.get("foo1")); + assertEquals("Expected 7 key value pairs", 7, dataAsMap.keySet().size()); + assertTrue(dataAsMap.containsKey("key")); + assertNull("value for \"key\" is null", dataAsMap.get("key")); + Double rawLong = (Double)dataAsMap.get("long"); + long longVal = rawLong.longValue(); + assertEquals(10_000_000_001L, longVal); + } + } + + /* + * This is a test which makes sure that html characters don't get + * escaped. We were seeing instances where the following happened which this + * test is trying to catch: + * + * before JSON deserialization: {"key": "value = 'foo', 'bar', 'baz'"} + * after JSON deserialization: {"key"; "value \u003d \u0027foo\u0027, \u0027bar\u0027, \u0027baz\u0027"} + */ + @Test + public void canDeserializeMetricWithSpecialChar() { + String json = "{\n" + + " \"marker\": \"marker\",\n" + + " \"timestamp\":\"30\",\n" + + " \"data\": {\n" + + " \"key\": \"value = 'foo', 'bar', 'baz'\"\n" + + " }\n" + + "}"; + BytemanMetric metric = gson.fromJson(json, BytemanMetric.class); + assertJsonEquals("{\"key\":\"value = 'foo', 'bar', 'baz'\"}", metric.getData()); + Map dataAsMap = metric.getDataAsMap(); + assertEquals("value = 'foo', 'bar', 'baz'", dataAsMap.get("key")); + } + + @Test + public void testWrite() { + BytemanMetric metric = new BytemanMetric(); + metric.setTimeStamp(100l); + metric.setJvmId("Vm-1"); + metric.setAgentId("Agent-1"); + metric.setMarker("Marker"); + metric.setData("{\"data\":\"This is data\"}"); + assertJsonEquals("{\"agentId\":\"Agent-1\",\"jvmId\":\"Vm-1\",\"marker\":\"Marker\",\"payload\":\"{\\\"data\\\":\\\"This is data\\\"}\",\"timeStamp\":{\"$numberLong\":\"100\"}}", gson.toJson(metric)); + } +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/JsonHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/JsonHelper.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,68 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal.typeadapter; + +public class JsonHelper { + + public static String buildJsonArray(int length) { + String elemFormat = + "{\n" + + " \"marker\": \"baz%d\",\n" + + " \"timestamp\":\"%d\",\n" + + " \"data\": {\n" + + " \"foo1\": \"ba\\\"r1\",\n" + + " \"foo2\": 42%d,\n" + + " \"foo3\": 42.%d,\n" + + " \"foo4\": false,\n" + + " \"foo5\": \"[]\",\n" + + " \"key\": null,\n" + + " \"long\": 10000000001\n" + + " }\n" + + "}"; + StringBuilder builder = new StringBuilder(); + builder.append("["); + for (int i = 0; i < length; i++) { + builder.append(String.format(elemFormat, i, 1234567890 + i, i, i)); + builder.append(","); + } + if (length > 0) { + builder.deleteCharAt(builder.length() - 1); + } + builder.append("]"); + return builder.toString(); + } +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/VmBytemanStatusTypeAdapterTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/VmBytemanStatusTypeAdapterTest.java Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,64 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.vm.byteman.agent.internal.typeadapter; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus; +import com.redhat.thermostat.vm.byteman.agent.internal.typeadapters.VmBytemanStatusTypeAdapter; + +import org.junit.Test; + +import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals; + +public class VmBytemanStatusTypeAdapterTest { + + @Test + public void testWrite() { + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeAdapter(VmBytemanStatus.class, new VmBytemanStatusTypeAdapter()); + Gson gson = builder.create(); + VmBytemanStatus status = new VmBytemanStatus(); + status.setTimeStamp(100l); + status.setAgentId("Agent-1"); + status.setJvmId("Vm-1"); + status.setListenPort(27518); + status.setRule("Rule"); + assertJsonEquals("{\"agentId\":\"Agent-1\",\"jvmId\":\"Vm-1\",\"timeStamp\":{\"$numberLong\":\"100\"},\"rule\":\"Rule\",\"listenPort\":27518}", gson.toJson(status)); + } + +} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/pom.xml --- a/plugins/vm-byteman/common/pom.xml Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ - - - - 4.0.0 - - thermostat-vm-byteman - com.redhat.thermostat - 1.99.12-SNAPSHOT - - thermostat-vm-byteman-common - bundle - Thermostat VM Byteman Common plugin - - - - org.apache.felix - maven-bundle-plugin - true - - - Red Hat, Inc. - com.redhat.thermostat.vm.byteman.common - - com.redhat.thermostat.vm.byteman.common, - com.redhat.thermostat.vm.byteman.common.command, - - - com.redhat.thermostat.vm.byteman.common.internal - - - <_nouses>true - - - - - org.apache.felix - maven-scr-plugin - - - generate-scr-scrdescriptor - - scr - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - test-jar - - - - - - - - - junit - junit - test - - - org.mockito - mockito-core - test - - - org.osgi - org.osgi.core - provided - - - org.osgi - org.osgi.compendium - provided - - - com.redhat.thermostat - thermostat-common-core - ${project.version} - - - com.redhat.thermostat - thermostat-common-command - ${project.version} - - - com.redhat.thermostat - thermostat-storage-core - ${project.version} - - - com.redhat.thermostat - thermostat-common-test - ${project.version} - test - - - com.redhat.thermostat - thermostat-storage-testutils - ${project.version} - test - - - com.google.code.gson - gson - - - - org.apache.felix - org.apache.felix.scr.annotations - - - diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetric.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetric.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common; - -import java.util.HashMap; -import java.util.Map; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonSyntaxException; -import com.redhat.thermostat.storage.core.Entity; -import com.redhat.thermostat.storage.core.Persist; -import com.redhat.thermostat.storage.model.BasePojo; -import com.redhat.thermostat.storage.model.TimeStampedPojo; - -@Entity -public class BytemanMetric extends BasePojo implements TimeStampedPojo { - - private static final Gson GSON = new GsonBuilder().serializeNulls().create(); - public static final String MARKER_NAME = "marker"; - public static final String TIMESTAMP_NAME = "timestamp"; - public static final String DATA_NAME = "data"; - private String vmId; - private String marker; - private String jsonPayload; - private long timestamp; - - public BytemanMetric(String writerId) { - super(writerId); - } - - public BytemanMetric() { - this(null); - } - - @Persist - public String getVmId() { - return vmId; - } - - @Persist - public void setVmId(String vmId) { - this.vmId = vmId; - } - - /** - * Get the marker for this Byteman metric. A marker can be thought of a - * category for related metrics. - * - * @return The marker for this metric. - */ - @Persist - public String getMarker() { - return marker; - } - - @Persist - public void setMarker(String marker) { - this.marker = marker; - } - - @Persist - public void setTimeStamp(long timestamp) { - this.timestamp = timestamp; - } - - @Persist - @Override - public long getTimeStamp() { - return timestamp; - } - - @Persist - public void setData(String json) { - this.jsonPayload = json; - } - - @Persist - public String getData() { - return jsonPayload; - } - - /** - * Get the metrics payload as raw JSON string. The payload is a JSON object - * in key, value form. Supported value types are {@code Boolean}, - * {@code String} and {@code Double}. - * - * @return The raw JSON string. - */ - public String getDataAsJson() { - return getData(); - } - - /** - * Get the metrics payload as parsed {@link Map}. Supported value types are - * {@code Boolean}, {@code String} and {@code Double}. - * - * @return The parsed JSON payload as {@link Map}. - */ - @SuppressWarnings("unchecked") - public Map getDataAsMap() { - try { - return (Map)GSON.fromJson(jsonPayload, HashMap.class); - } catch (JsonSyntaxException e) { - throw new RuntimeException("Payload not in expected format. Payload was: " + jsonPayload); - } - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricDataExtractor.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricDataExtractor.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -public class BytemanMetricDataExtractor { - - private final Set keySet; - - public BytemanMetricDataExtractor() { - this.keySet = new HashSet<>(); - } - - public void mineMetric(BytemanMetric m) { - Objects.requireNonNull(m); - Map dataMap = m.getDataAsMap(); - if (dataMap != null) { - for (String key: dataMap.keySet()) { - keySet.add(key); - } - } - } - - /** - * - * @return A sorted list of the set of keys. - */ - public List getSortedKeySet() { - List returnedList = new ArrayList<>(keySet); - Collections.sort(returnedList); - return returnedList; - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricTypeAdapterFactory.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricTypeAdapterFactory.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common; - -import com.google.gson.Gson; -import com.google.gson.TypeAdapter; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.redhat.thermostat.vm.byteman.common.internal.BytemanMetricTypeAdapter; - -public class BytemanMetricTypeAdapterFactory implements TypeAdapterFactory { - - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - Class rawType = type.getRawType(); - if (rawType == BytemanMetric.class) { - @SuppressWarnings("unchecked") - TypeAdapter ta = (TypeAdapter)new BytemanMetricTypeAdapter(gson); - return ta; - } - return null; - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/VmBytemanDAO.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/VmBytemanDAO.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common; - -import java.util.List; - -import com.redhat.thermostat.common.model.Range; -import com.redhat.thermostat.storage.core.AgentId; -import com.redhat.thermostat.storage.core.VmId; - -public interface VmBytemanDAO { - - void addMetric(BytemanMetric metric); - - void addOrReplaceBytemanStatus(VmBytemanStatus status); - - VmBytemanStatus findBytemanStatus(VmId vmId); - - List findBytemanMetrics(Range timeRange, VmId vmId, AgentId agentId); -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/VmBytemanStatus.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/VmBytemanStatus.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common; - -import com.redhat.thermostat.storage.core.Entity; -import com.redhat.thermostat.storage.core.Persist; -import com.redhat.thermostat.storage.model.BasePojo; -import com.redhat.thermostat.storage.model.TimeStampedPojo; - -@Entity -public class VmBytemanStatus extends BasePojo implements TimeStampedPojo { - - private String vmId; - private long timestamp; - private String rule; - private int listenPort; - - public VmBytemanStatus(String writerId) { - super(writerId); - } - - public VmBytemanStatus() { - super(null); - } - - @Persist - public String getVmId() { - return vmId; - } - - @Persist - public void setVmId(String vmId) { - this.vmId = vmId; - } - - @Persist - public void setTimeStamp(long timestamp) { - this.timestamp = timestamp; - } - - @Persist - @Override - public long getTimeStamp() { - return timestamp; - } - - @Persist - public void setRule(String rule) { - this.rule = rule; - } - - @Persist - public String getRule() { - return rule; - } - - @Persist - public void setListenPort(int port) { - this.listenPort = port; - } - - @Persist - public int getListenPort() { - return listenPort; - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequest.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequest.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.command; - -import java.net.InetSocketAddress; - -import com.redhat.thermostat.common.command.Request; -import com.redhat.thermostat.common.command.Request.RequestType; -import com.redhat.thermostat.storage.model.VmInfo; - -public class BytemanRequest { - - public static enum RequestAction { - LOAD_RULES(0), - UNLOAD_RULES(1), - ; - - private int actionId; - private RequestAction(int id) { - this.actionId = id; - } - - public static RequestAction fromIntString(String id) { - int intId; - try { - intId = Integer.parseInt(id); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Unknown action: " + id); - } - switch(intId) { - case(0): return LOAD_RULES; - case(1): return UNLOAD_RULES; - default: - throw new IllegalArgumentException("Unknown action: " + id); - } - } - - private String toIntString() { - return Integer.toString(actionId); - } - } - - private static final String CMD_CHANN_ACTION_NAME = "vm-byteman-instrument"; - private static final String RECEIVER = "com.redhat.thermostat.vm.byteman.agent.internal.BytemanRequestReceiver"; - - public static final String VM_ID_PARAM_NAME = "vm-id"; - public static final String VM_PID_PARAM_NAME = "vm-pid"; - public static final String ACTION_PARAM_NAME = "byteman-action"; - public static final String LISTEN_PORT_PARAM_NAME = "listen-port"; - public static final String RULE_PARAM_NAME = "byteman-rule"; - public static final int NOT_ATTACHED_PORT = -1; - - public static Request create(InetSocketAddress address, VmInfo vmInfo, RequestAction action, int listenPort) { - Request req = new Request(RequestType.RESPONSE_EXPECTED, address); - req.setReceiver(RECEIVER); - req.setParameter(Request.ACTION, CMD_CHANN_ACTION_NAME); - req.setParameter(VM_ID_PARAM_NAME, vmInfo.getVmId()); - req.setParameter(VM_PID_PARAM_NAME, Integer.toString(vmInfo.getVmPid())); - req.setParameter(ACTION_PARAM_NAME, action.toIntString()); - req.setParameter(LISTEN_PORT_PARAM_NAME, Integer.toString(listenPort)); - return req; - } - - public static Request create(InetSocketAddress address, VmInfo vmInfo, RequestAction action, int listenPort, String rule) { - Request req = create(address, vmInfo, action, listenPort); - req.setParameter(RULE_PARAM_NAME, rule); - return req; - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestResponseListener.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestResponseListener.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.command; - -import java.util.concurrent.CountDownLatch; - -import com.redhat.thermostat.common.command.Request; -import com.redhat.thermostat.common.command.RequestResponseListener; -import com.redhat.thermostat.common.command.Response; -import com.redhat.thermostat.shared.locale.Translate; -import com.redhat.thermostat.vm.byteman.common.internal.LocaleResources; - -public class BytemanRequestResponseListener implements RequestResponseListener { - - private static final Translate t = LocaleResources.createLocalizer(); - private final CountDownLatch latch; - private String errorMsg = ""; - private boolean isError = false; - - public BytemanRequestResponseListener(CountDownLatch latch) { - this.latch = latch; - } - - @Override - public void fireComplete(Request request, Response response) { - switch(response.getType()) { - case AUTH_FAILED: - isError = true; - errorMsg = t.localize(LocaleResources.REQUEST_FAILED_AUTH_ISSUE).getContents(); - break; - case ERROR: - isError = true; - errorMsg = t.localize(LocaleResources.REQUEST_FAILED_UNKNOWN_ISSUE).getContents(); - break; - case OK: - break; - default: - isError = true; - errorMsg = t.localize(LocaleResources.ERROR_UNKNOWN_RESPONSE, response.getType().toString()).getContents(); - } - latch.countDown(); - } - - public String getErrorMessage() { - return errorMsg; - } - - public boolean isError() { - return isError; - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapter.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapter.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import com.google.gson.Gson; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; -import com.redhat.thermostat.vm.byteman.common.BytemanMetric; - -public class BytemanMetricTypeAdapter extends TypeAdapter { - - private final Gson gson; - - public BytemanMetricTypeAdapter(Gson gson) { - this.gson = gson; - } - - @Override - public BytemanMetric read(JsonReader reader) throws IOException { - // handle null - if (reader.peek() == JsonToken.NULL) { - reader.nextNull(); - return null; - } - - reader.beginObject(); - BytemanMetric metric = parseMetric(reader); - reader.endObject(); - return metric; - } - - @Override - public void write(JsonWriter writer, BytemanMetric metric) throws IOException { - throw new RuntimeException("Not implemented"); - } - - @SuppressWarnings("unchecked") - private BytemanMetric parseMetric(JsonReader reader) throws IOException { - Map values = new HashMap<>(); - while (reader.hasNext()) { - String name = reader.nextName(); - switch(name) { - case BytemanMetric.MARKER_NAME: - values.put(BytemanMetric.MARKER_NAME, reader.nextString()); - break; - case BytemanMetric.TIMESTAMP_NAME: - values.put(BytemanMetric.TIMESTAMP_NAME, Long.valueOf(reader.nextString())); - break; - case BytemanMetric.DATA_NAME: - Map data = getDataValues(reader); - values.put(BytemanMetric.DATA_NAME, data); - break; - default: - throw new IllegalStateException("Unknown name: '" + name + "'"); - } - } - BytemanMetric metric = new BytemanMetric(); - metric.setMarker((String)values.get(BytemanMetric.MARKER_NAME)); - metric.setTimeStamp((Long)values.get(BytemanMetric.TIMESTAMP_NAME)); - metric.setData(mapToJson((Map)values.get(BytemanMetric.DATA_NAME))); - return metric; - } - - private String mapToJson(Map map) { - return gson.toJson(map, HashMap.class); - } - - private Map getDataValues(JsonReader reader) throws IOException { - return gson.fromJson(reader, HashMap.class); - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricWebTypeAdapter.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricWebTypeAdapter.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import com.redhat.thermostat.vm.byteman.common.BytemanMetric; - -import java.io.IOException; - -public class BytemanMetricWebTypeAdapter extends TypeAdapter { - - private static final String TYPE_LONG = "$numberLong"; - private static final String VM_ID = "vmId"; - private static final String AGENT_ID = "agentId"; - private static final String MARKER = "marker"; - private static final String JSON_PAYLOAD = "jsonPayload"; - private static final String TIMESTAMP = "timeStamp"; - - @Override - public BytemanMetric read(JsonReader in) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void write(JsonWriter out, BytemanMetric metric) throws IOException { - out.beginObject(); - out.name(AGENT_ID); - out.value(metric.getAgentId()); - out.name(VM_ID); - out.value(metric.getVmId()); - out.name(MARKER); - out.value(metric.getMarker()); - out.name(JSON_PAYLOAD); - out.value(metric.getDataAsJson()); - out.name(TIMESTAMP); - writeLong(out, metric.getTimeStamp()); - out.endObject(); - } - - private void writeLong(JsonWriter out, long value) throws IOException { - // Write MongoDB representation of a Long - out.beginObject(); - out.name(TYPE_LONG); - out.value(String.valueOf(value)); - out.endObject(); - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/LocaleResources.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/LocaleResources.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import com.redhat.thermostat.shared.locale.Translate; - -public enum LocaleResources { - - REQUEST_FAILED_AUTH_ISSUE, - REQUEST_FAILED_UNKNOWN_ISSUE, - ERROR_UNKNOWN_RESPONSE, - ; - - static final String RESOURCE_BUNDLE = LocaleResources.class.getPackage().getName() + ".strings"; - - public static Translate createLocalizer() { - return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class); - } -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanDAOImpl.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanDAOImpl.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,183 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import java.util.List; -import java.util.logging.Logger; - -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.Service; - -import com.redhat.thermostat.common.model.Range; -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.storage.core.AgentId; -import com.redhat.thermostat.storage.core.Category; -import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.PreparedStatement; -import com.redhat.thermostat.storage.core.Storage; -import com.redhat.thermostat.storage.core.VmId; -import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter; -import com.redhat.thermostat.storage.dao.AbstractDao; -import com.redhat.thermostat.storage.dao.AbstractDaoQuery; -import com.redhat.thermostat.storage.dao.AbstractDaoStatement; -import com.redhat.thermostat.vm.byteman.common.BytemanMetric; -import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; -import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus; - -@Component -@Service(value = VmBytemanDAO.class) -public class VmBytemanDAOImpl extends AbstractDao implements VmBytemanDAO { - - static final Key MARKER = new Key<>("marker"); - static final Key DATA = new Key<>("data"); - static final Key RULE = new Key<>("rule"); - static final Key PORT = new Key<>("listenPort"); - - static final Category VM_BYTEMAN_METRICS_CATEGORY = new Category<>( - "vm-byteman-metrics", - BytemanMetric.class, - Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, - MARKER, DATA); - - static final Category VM_BYTEMAN_STATUS_CATEGORY = new Category<>( - "vm-byteman-status", - VmBytemanStatus.class, - Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP, - RULE, PORT); - - static final String REPLACE_OR_ADD_STATUS_DESC = "REPLACE " + VM_BYTEMAN_STATUS_CATEGORY.getName() + - " SET '" + Key.AGENT_ID.getName() + "' = ?s , " + - "'" + Key.VM_ID.getName() + "' = ?s , " + - "'" + Key.TIMESTAMP.getName() + "' = ?l , " + - "'" + RULE.getName() + "' = ?s , " + - "'" + PORT.getName() + "' = ?i WHERE " - + "'" + Key.VM_ID.getName() + "' = ?s"; - - static final String ADD_METRIC_DESC = "ADD " + VM_BYTEMAN_METRICS_CATEGORY.getName() + - " SET '" + Key.AGENT_ID.getName() + "' = ?s , " + - "'" + Key.VM_ID.getName() + "' = ?s , " + - "'" + Key.TIMESTAMP.getName() + "' = ?l , " + - "'" + MARKER.getName() + "' = ?s , " + - "'" + DATA.getName() + "' = ?s"; - - static final String QUERY_VM_BYTEMAN_STATUS = "QUERY " + VM_BYTEMAN_STATUS_CATEGORY.getName() + - " WHERE '" + Key.VM_ID.getName() + "' = ?s LIMIT 1"; - - @Reference - private Storage storage; - private VmTimeIntervalPojoListGetter intervalGetter; - - public VmBytemanDAOImpl() { - // Default constructor for DS - } - - VmBytemanDAOImpl(Storage storage) { - this.storage = storage; - } - - @Activate - private void activate() { - storage.registerCategory(VM_BYTEMAN_METRICS_CATEGORY); - storage.registerCategory(VM_BYTEMAN_STATUS_CATEGORY); - intervalGetter = new VmTimeIntervalPojoListGetter<>(storage, VM_BYTEMAN_METRICS_CATEGORY); - } - - @Override - public void addMetric(final BytemanMetric metric) { - executeStatement(new AbstractDaoStatement(storage, VM_BYTEMAN_METRICS_CATEGORY, ADD_METRIC_DESC) { - - @Override - public PreparedStatement customize(PreparedStatement preparedStatement) { - preparedStatement.setString(0, metric.getAgentId()); - preparedStatement.setString(1, metric.getVmId()); - preparedStatement.setLong(2, metric.getTimeStamp()); - preparedStatement.setString(3, metric.getMarker()); - preparedStatement.setString(4, metric.getDataAsJson()); - return preparedStatement; - } - }); - - } - - @Override - public List findBytemanMetrics(Range timeRange, - VmId vmId, AgentId agentId) { - return intervalGetter.getLatest(agentId, vmId, timeRange.getMin(), timeRange.getMax()); - } - - @Override - protected Logger getLogger() { - return LoggingUtils.getLogger(VmBytemanDAOImpl.class); - } - - @Override - public void addOrReplaceBytemanStatus(final VmBytemanStatus status) { - executeStatement(new AbstractDaoStatement(storage, VM_BYTEMAN_STATUS_CATEGORY, REPLACE_OR_ADD_STATUS_DESC) { - - @Override - public PreparedStatement customize(PreparedStatement preparedStatement) { - preparedStatement.setString(0, status.getAgentId()); - preparedStatement.setString(1, status.getVmId()); - preparedStatement.setLong(2, status.getTimeStamp()); - preparedStatement.setString(3, status.getRule()); - preparedStatement.setInt(4, status.getListenPort()); - preparedStatement.setString(5, status.getVmId()); - return preparedStatement; - } - }); - - } - - @Override - public VmBytemanStatus findBytemanStatus(final VmId vmId) { - List result = executeQuery(new AbstractDaoQuery(storage, VM_BYTEMAN_STATUS_CATEGORY, QUERY_VM_BYTEMAN_STATUS) { - - @Override - public PreparedStatement customize(PreparedStatement preparedStatement) { - preparedStatement.setString(0, vmId.get()); - return preparedStatement; - } - }).asList(); - if (result.isEmpty()) { - return null; - } - return result.get(0); - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanMetricDAOCategoryRegistration.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanMetricDAOCategoryRegistration.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import java.util.HashSet; -import java.util.Set; - -import com.redhat.thermostat.storage.core.auth.CategoryRegistration; - -public class VmBytemanMetricDAOCategoryRegistration - implements CategoryRegistration { - - @Override - public Set getCategoryNames() { - Set categories = new HashSet<>(1); - categories.add(VmBytemanDAOImpl.VM_BYTEMAN_METRICS_CATEGORY.getName()); - categories.add(VmBytemanDAOImpl.VM_BYTEMAN_STATUS_CATEGORY.getName()); - return categories; - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanMetricDAOImplStatementDescriptorRegistration.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanMetricDAOImplStatementDescriptorRegistration.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import java.util.HashSet; -import java.util.Set; - -import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter; -import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration; - -public class VmBytemanMetricDAOImplStatementDescriptorRegistration - implements StatementDescriptorRegistration { - - static final String intervalDescriptor = String.format( - VmTimeIntervalPojoListGetter.VM_INTERVAL_QUERY_FORMAT, - VmBytemanDAOImpl.VM_BYTEMAN_METRICS_CATEGORY.getName()); - - @Override - public Set getStatementDescriptors() { - Set descs = new HashSet<>(7); - descs.add(VmBytemanDAOImpl.ADD_METRIC_DESC); - descs.add(intervalDescriptor); - descs.add(VmBytemanDAOImpl.REPLACE_OR_ADD_STATUS_DESC); - descs.add(VmBytemanDAOImpl.QUERY_VM_BYTEMAN_STATUS); - return descs; - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanStatusTypeAdapter.java --- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanStatusTypeAdapter.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus; - -import java.io.IOException; - -public class VmBytemanStatusTypeAdapter extends TypeAdapter { - - private static final String TYPE_LONG = "$numberLong"; - private static final String VM_ID = "vmId"; - private static final String AGENT_ID = "agentId"; - private static final String TIMESTAMP = "timeStamp"; - private static final String RULE = "rule"; - private static final String LISTEN_PORT = "listenPort"; - - @Override - public VmBytemanStatus read(JsonReader in) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void write(JsonWriter out, VmBytemanStatus status) throws IOException { - out.beginObject(); - out.name(AGENT_ID); - out.value(status.getAgentId()); - out.name(VM_ID); - out.value(status.getVmId()); - out.name(TIMESTAMP); - writeLong(out, status.getTimeStamp()); - out.name(RULE); - out.value(status.getRule()); - out.name(LISTEN_PORT); - out.value(status.getListenPort()); - out.endObject(); - } - - private void writeLong(JsonWriter out, long value) throws IOException { - // Write MongoDB representation of a Long - out.beginObject(); - out.name(TYPE_LONG); - out.value(String.valueOf(value)); - out.endObject(); - } -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.CategoryRegistration --- a/plugins/vm-byteman/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.CategoryRegistration Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -com.redhat.thermostat.vm.byteman.common.internal.VmBytemanMetricDAOCategoryRegistration \ No newline at end of file diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration --- a/plugins/vm-byteman/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -com.redhat.thermostat.vm.byteman.common.internal.VmBytemanMetricDAOImplStatementDescriptorRegistration \ No newline at end of file diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/main/resources/com/redhat/thermostat/vm/byteman/common/internal/strings.properties --- a/plugins/vm-byteman/common/src/main/resources/com/redhat/thermostat/vm/byteman/common/internal/strings.properties Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -REQUEST_FAILED_AUTH_ISSUE = Request failed due to authentication/authorization issues. -REQUEST_FAILED_UNKNOWN_ISSUE = Request failed for some unknown reason. -ERROR_UNKNOWN_RESPONSE = Unknown response: {0} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricDataExtractorTest.java --- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricDataExtractorTest.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -public class BytemanMetricDataExtractorTest { - - private BytemanMetricDataExtractor extractor; - - @Before - public void setup() { - extractor = new BytemanMetricDataExtractor(); - } - - @Test - public void testEmptyKeySet() { - List actual = extractor.getSortedKeySet(); - assertTrue(actual.isEmpty()); - } - - @Test - public void testAdditiveKeySet() { - String firstKey = "zoo"; - BytemanMetric first = new BytemanMetric(); - first.setData("{\"" + firstKey + "\": \"bar\"}"); - extractor.mineMetric(first); - List actual = extractor.getSortedKeySet(); - assertEquals(1, actual.size()); - assertEquals(firstKey, actual.get(0)); - - BytemanMetric second = new BytemanMetric(); - String secondKey = "secondKey"; - second.setData("{\"" + secondKey + "\": \"baz\"}"); - extractor.mineMetric(second); - actual = extractor.getSortedKeySet(); - assertEquals(2, actual.size()); - - // verify sorting - assertEquals(secondKey, actual.get(0)); - assertEquals(firstKey, actual.get(1)); - } - - @Test - public void testDuplicateKey() { - String firstKey = "zoo"; - BytemanMetric first = new BytemanMetric(); - first.setData("{\"" + firstKey + "\": \"bar\"}"); - extractor.mineMetric(first); - List actual = extractor.getSortedKeySet(); - assertEquals(1, actual.size()); - assertEquals(firstKey, actual.get(0)); - - extractor.mineMetric(first); - actual = extractor.getSortedKeySet(); - assertEquals(1, actual.size()); - assertEquals(firstKey, actual.get(0)); - } - - @Test - public void extractionDoesNotFailIfNoData() { - BytemanMetric m = new BytemanMetric(); - extractor.mineMetric(m); // this shall not fail with NPE - List actual = extractor.getSortedKeySet(); - assertTrue(actual.isEmpty()); - } - - @Test(expected = NullPointerException.class) - public void mineRequiresNonNull() { - extractor.mineMetric(null); - } - - @Test - public void canExtractListOfMetrics() { - String[] keys = new String[] { - "001_first", "002_second", "003_third", "004_fourth" - }; - List mList = buildMetrics(keys); - for (BytemanMetric metric: mList) { - extractor.mineMetric(metric); - } - List keySet = extractor.getSortedKeySet(); - assertEquals(4, keySet.size()); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(keys[0], keySet.get(0)); - } - - } - - private List buildMetrics(String[] keys) { - List list = new ArrayList<>(); - for (String key: keys) { - BytemanMetric m = new BytemanMetric(); - m.setData("{\"" + key + "\": \"" + key + "_value\"}"); - list.add(m); - } - return list; - } -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/JsonHelper.java --- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/JsonHelper.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common; - -public class JsonHelper { - - public static String buildJsonArray(int length) { - String elemFormat = - "{\n" + - " \"marker\": \"baz%d\",\n" + - " \"timestamp\":\"%d\",\n" + - " \"data\": {\n" + - " \"foo1\": \"ba\\\"r1\",\n" + - " \"foo2\": 42%d,\n" + - " \"foo3\": 42.%d,\n" + - " \"foo4\": false,\n" + - " \"foo5\": \"[]\",\n" + - " \"key\": null,\n" + - " \"long\": 10000000001\n" + - " }\n" + - "}"; - StringBuilder builder = new StringBuilder(); - builder.append("["); - for (int i = 0; i < length; i++) { - builder.append(String.format(elemFormat, i, 1234567890 + i, i, i)); - builder.append(","); - } - if (length > 0) { - builder.deleteCharAt(builder.length() - 1); - } - builder.append("]"); - return builder.toString(); - } -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestResponseListenerTest.java --- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestResponseListenerTest.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.command; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import java.util.concurrent.CountDownLatch; - -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.common.command.Request; -import com.redhat.thermostat.common.command.Response; -import com.redhat.thermostat.common.command.Response.ResponseType; -import com.redhat.thermostat.vm.byteman.common.command.BytemanRequestResponseListener; - -public class BytemanRequestResponseListenerTest { - - private BytemanRequestResponseListener listener; - private CountDownLatch latch; - - @Before - public void setup() { - latch = mock(CountDownLatch.class); - listener = new BytemanRequestResponseListener(latch); - } - - @Test - public void testAuthIssue() { - listener.fireComplete(mock(Request.class), new Response(ResponseType.AUTH_FAILED)); - verify(latch).countDown(); - assertTrue(listener.isError()); - String errOut = listener.getErrorMessage(); - assertTrue(errOut.contains("authentication")); - assertTrue(errOut.contains("issue")); - } - - @Test - public void testSuccess() { - listener.fireComplete(mock(Request.class), new Response(ResponseType.OK)); - verify(latch).countDown(); - assertFalse(listener.isError()); - } - - @Test - public void testUnknownError() { - listener.fireComplete(mock(Request.class), new Response(ResponseType.ERROR)); - verify(latch).countDown(); - assertTrue(listener.isError()); - String errOut = listener.getErrorMessage(); - assertTrue(errOut.contains("unknown")); - assertTrue(errOut.contains("reason")); - } - - @Test - public void testUnknownType() { - listener.fireComplete(mock(Request.class), new Response(ResponseType.NOK)); - verify(latch).countDown(); - assertTrue(listener.isError()); - String errOut = listener.getErrorMessage(); - assertEquals("Unknown response: NOK", errOut); - } -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestTest.java --- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestTest.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.command; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; - -import java.net.InetSocketAddress; - -import org.junit.Test; - -import com.redhat.thermostat.common.command.Request; -import com.redhat.thermostat.common.command.Request.RequestType; -import com.redhat.thermostat.storage.model.VmInfo; -import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest.RequestAction; - -public class BytemanRequestTest { - - @Test - public void testCreateRequestWithRule() { - Request req = BytemanRequest.create(new InetSocketAddress("127.0.0.1", 12000), mock(VmInfo.class), RequestAction.LOAD_RULES, 3, "foo-bar"); - assertEquals(RequestType.RESPONSE_EXPECTED, req.getType()); - } -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapterTest.java --- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapterTest.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.redhat.thermostat.vm.byteman.common.BytemanMetric; -import com.redhat.thermostat.vm.byteman.common.BytemanMetricTypeAdapterFactory; -import com.redhat.thermostat.vm.byteman.common.JsonHelper; - -public class BytemanMetricTypeAdapterTest { - - private static final double DELTA = 0.001; - - private Gson gson; - - @Before - public void setup() { - gson = new GsonBuilder() - .registerTypeAdapterFactory(new BytemanMetricTypeAdapterFactory()) - .disableHtmlEscaping() - .serializeNulls() - .create(); - } - - @Test - public void canDeserializeArrayOfMetrics() { - String json = JsonHelper.buildJsonArray(10); - BytemanMetric[] metrics = gson.fromJson(json, BytemanMetric[].class); - assertEquals(10, metrics.length); - for (int i = 0; i < 10; i++) { - assertEquals("baz" + i, metrics[i].getMarker()); - assertEquals(1234567890 + i, metrics[i].getTimeStamp()); - Map dataAsMap = metrics[i].getDataAsMap(); - assertFalse((Boolean)dataAsMap.get("foo4")); - assertEquals("[]", (String)dataAsMap.get("foo5")); - double foo3Val = (double)dataAsMap.get("foo3"); - String foo3Str = String.format("42.%d", i); - double expectedFoo3Val = Double.parseDouble(foo3Str); - assertEquals(expectedFoo3Val, foo3Val, DELTA); - double foo2Val = (double)dataAsMap.get("foo2"); - String foo2Str = String.format("42%d.0", i); - double expectedFoo2Val = Double.parseDouble(foo2Str); - assertEquals(expectedFoo2Val, foo2Val, DELTA); - assertEquals("ba\"r1", (String)dataAsMap.get("foo1")); - assertEquals("Expected 7 key value pairs", 7, dataAsMap.keySet().size()); - assertTrue(dataAsMap.containsKey("key")); - assertNull("value for \"key\" is null", dataAsMap.get("key")); - Double rawLong = (Double)dataAsMap.get("long"); - long longVal = rawLong.longValue(); - assertEquals(10_000_000_001L, longVal); - } - } - - /* - * This is a test which makes sure that html characters don't get - * escaped. We were seeing instances where the following happened which this - * test is trying to catch: - * - * before JSON deserialization: {"key": "value = 'foo', 'bar', 'baz'"} - * after JSON deserialization: {"key"; "value \u003d \u0027foo\u0027, \u0027bar\u0027, \u0027baz\u0027"} - */ - @Test - public void canDeserializeMetricWithSpecialChar() { - String json = "{\n" + - " \"marker\": \"marker\",\n" + - " \"timestamp\":\"30\",\n" + - " \"data\": {\n" + - " \"key\": \"value = 'foo', 'bar', 'baz'\"\n" + - " }\n" + - "}"; - BytemanMetric metric = gson.fromJson(json, BytemanMetric.class); - assertJsonEquals("{\"key\":\"value = 'foo', 'bar', 'baz'\"}", metric.getData()); - Map dataAsMap = metric.getDataAsMap(); - assertEquals("value = 'foo', 'bar', 'baz'", dataAsMap.get("key")); - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricWebTypeAdapterTest.java --- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricWebTypeAdapterTest.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.redhat.thermostat.vm.byteman.common.BytemanMetric; -import org.junit.Test; - -import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals; - -public class BytemanMetricWebTypeAdapterTest { - - @Test - public void testWrite() { - GsonBuilder builder = new GsonBuilder(); - builder.registerTypeAdapter(BytemanMetric.class, new BytemanMetricWebTypeAdapter()); - Gson gson = builder.create(); - BytemanMetric metric = new BytemanMetric(); - metric.setTimeStamp(100l); - metric.setVmId("Vm-1"); - metric.setAgentId("Agent-1"); - metric.setMarker("Marker"); - metric.setData("{\"data\":\"This is data\"}"); - assertJsonEquals("{\"agentId\":\"Agent-1\",\"vmId\":\"Vm-1\",\"marker\":\"Marker\",\"jsonPayload\":\"{\\\"data\\\":\\\"This is data\\\"}\",\"timeStamp\":{\"$numberLong\":\"100\"}}", gson.toJson(metric)); - } -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/LocaleResourcesTest.java --- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/LocaleResourcesTest.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest; - -public class LocaleResourcesTest extends AbstractLocaleResourcesTest { - - @Override - protected Class getEnumClass() { - return LocaleResources.class; - } - - @Override - protected String getResourceBundle() { - return LocaleResources.RESOURCE_BUNDLE; - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanStatusTypeAdapterTest.java --- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanStatusTypeAdapterTest.java Mon Sep 18 14:04:16 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.vm.byteman.common.internal; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus; -import org.junit.Test; - -import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals; - -public class VmBytemanStatusTypeAdapterTest { - - @Test - public void testWrite() { - GsonBuilder builder = new GsonBuilder(); - builder.registerTypeAdapter(VmBytemanStatus.class, new VmBytemanStatusTypeAdapter()); - Gson gson = builder.create(); - VmBytemanStatus status = new VmBytemanStatus(); - status.setTimeStamp(100l); - status.setAgentId("Agent-1"); - status.setVmId("Vm-1"); - status.setListenPort(27518); - status.setRule("Rule"); - assertJsonEquals("{\"agentId\":\"Agent-1\",\"vmId\":\"Vm-1\",\"timeStamp\":{\"$numberLong\":\"100\"},\"rule\":\"Rule\",\"listenPort\":27518}", gson.toJson(status)); - } - -} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/distribution/assemblies/plugin-assembly.xml --- a/plugins/vm-byteman/distribution/assemblies/plugin-assembly.xml Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/distribution/assemblies/plugin-assembly.xml Fri Sep 22 10:10:52 2017 -0400 @@ -43,28 +43,34 @@ zip - ${thermostat.plugin} - true + false - com.redhat.thermostat:thermostat-vm-byteman-common com.redhat.thermostat:thermostat-vm-byteman-agent org.jboss.byteman:byteman-submit org.jboss.byteman:byteman-install false true + plugins/${thermostat.plugin} - - - thermostat-plugin.xml - / + + + + thermostat-plugin.xml + + plugins/${thermostat.plugin} true - - + + + configFiles + etc/plugins.d/${thermostat.plugin} + true + + diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/distribution/configFiles/gateway.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-byteman/distribution/configFiles/gateway.properties Fri Sep 22 10:10:52 2017 -0400 @@ -0,0 +1,2 @@ +# Web socket base URL to the commands microservice provided by the Thermostat web gateway +gatewayURL=https://127.0.0.1:30000/jvm-byteman/0.0.1 diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/distribution/thermostat-plugin.xml --- a/plugins/vm-byteman/distribution/thermostat-plugin.xml Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/distribution/thermostat-plugin.xml Fri Sep 22 10:10:52 2017 -0400 @@ -41,7 +41,6 @@ agent - com.redhat.thermostat.vm.byteman.common${project.version} com.redhat.thermostat.vm.byteman.agent${project.version} diff -r e67aeba2003a -r 22f2b3ea3609 plugins/vm-byteman/pom.xml --- a/plugins/vm-byteman/pom.xml Mon Sep 18 14:04:16 2017 +0200 +++ b/plugins/vm-byteman/pom.xml Fri Sep 22 10:10:52 2017 -0400 @@ -54,7 +54,6 @@ byteman-helper byteman-helper-distro agent - common distribution