Mercurial > hg > thermostat
changeset 2527:edf71d9262f8
Copy IPC properties file to world-readable location at runtime
Reviewed-by: jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-November/021565.html
line wrap: on
line diff
--- a/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/Activator.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/Activator.java Tue Nov 15 18:18:31 2016 -0500 @@ -77,7 +77,7 @@ SSLConfiguration sslConf = services.get(SSLConfiguration.class); AgentIPCService ipcService = services.get(AgentIPCService.class); CommandChannelDelegate confServer = new CommandChannelDelegate(receivers, sslConf, - paths.getSystemBinRoot(), ipcService, paths.getUserIPCConfigurationFile()); + paths.getSystemBinRoot(), ipcService); confServerRegistration = context.registerService(ConfigurationServer.class.getName(), confServer, null); }
--- a/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java Tue Nov 15 18:18:31 2016 -0500 @@ -90,7 +90,6 @@ private final StorageGetter storageGetter; private final File binPath; private final AgentIPCService ipcService; - private final File ipcConfig; private final CountDownLatch readyLatch; private final SSLConfigurationEncoder sslEncoder; private final AgentRequestDecoder requestDecoder; @@ -102,15 +101,15 @@ private AtomicInteger state; CommandChannelDelegate(ReceiverRegistry receivers, SSLConfiguration sslConf, File binPath, - AgentIPCService ipcService, File ipcConfig) { - this(receivers, sslConf, binPath, ipcService, ipcConfig, new CountDownLatch(1), new SSLConfigurationEncoder(), + AgentIPCService ipcService) { + this(receivers, sslConf, binPath, ipcService, new CountDownLatch(1), new SSLConfigurationEncoder(), new AgentRequestDecoder(), new AgentResponseEncoder(), new StorageGetter(), new ProcessUserInfoBuilder(), new FileSystemUtils(), new ProcessCreator()); } /** For testing only */ CommandChannelDelegate(ReceiverRegistry receivers, SSLConfiguration sslConf, File binPath, - AgentIPCService ipcService, File ipcConfig, CountDownLatch readyLatch, SSLConfigurationEncoder sslEncoder, + AgentIPCService ipcService, CountDownLatch readyLatch, SSLConfigurationEncoder sslEncoder, AgentRequestDecoder requestDecoder, AgentResponseEncoder responseEncoder, StorageGetter getter, ProcessUserInfoBuilder userInfoBuilder, FileSystemUtils fsUtils, ProcessCreator procCreator) { this.storageGetter = getter; @@ -118,7 +117,6 @@ this.sslConf = sslConf; this.binPath = binPath; this.ipcService = ipcService; - this.ipcConfig = ipcConfig; this.readyLatch = readyLatch; this.sslEncoder = sslEncoder; this.requestDecoder = requestDecoder; @@ -226,6 +224,7 @@ } private void startServer(String hostname, int port) throws IOException { + File ipcConfig = ipcService.getConfigurationFile(); String[] processArgs = OS.IS_UNIX ? new String[]{ binPath.getAbsolutePath() + File.separator + CMD_NAME, hostname, String.valueOf(port), ipcConfig.getAbsolutePath() }
--- a/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java Tue Nov 15 18:18:31 2016 -0500 @@ -142,11 +142,12 @@ when(sslConfEncoder.encodeAsJson(sslConf)).thenReturn(ENCODED_SSL_CONFIG); when(processCreator.startProcess(any(ProcessBuilder.class))).thenReturn(process); + when(ipcService.getConfigurationFile()).thenReturn(ipcConfig); latch = mock(CountDownLatch.class); fsUtils = mock(FileSystemUtils.class); userInfoBuilder = mock(ProcessUserInfoBuilder.class); - delegate = new CommandChannelDelegate(receivers, sslConf, binPath, ipcService, ipcConfig, + delegate = new CommandChannelDelegate(receivers, sslConf, binPath, ipcService, latch, sslConfEncoder, requestDecoder, responseEncoder, storageGetter, userInfoBuilder, fsUtils, processCreator);
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java Tue Nov 15 18:18:31 2016 -0500 @@ -120,8 +120,7 @@ AgentIPCService ipcService = services.get(AgentIPCService.class); CommonPaths paths = services.get(CommonPaths.class); UserNameUtil util = services.get(UserNameUtil.class); - pool = new MXBeanConnectionPoolImpl(paths.getSystemBinRoot(), util, - ipcService, paths.getUserIPCConfigurationFile()); + pool = new MXBeanConnectionPoolImpl(paths.getSystemBinRoot(), util, ipcService); context.registerService(MXBeanConnectionPool.class, pool, null); // Used only internally context.registerService(MXBeanConnectionPoolControl.class, pool, null);
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java Tue Nov 15 18:18:31 2016 -0500 @@ -79,7 +79,6 @@ private final File binPath; private final ProcessUserInfoBuilder userInfoBuilder; private final AgentIPCService ipcService; - private final File ipcConfigFile; private final FileSystemUtils fsUtils; // Keep track of IPC servers we created private final Set<String> ipcServerNames; @@ -94,20 +93,18 @@ private MXBeanConnectionPoolEntry currentNewEntry; private boolean started; - public MXBeanConnectionPoolImpl(File binPath, UserNameUtil userNameUtil, - AgentIPCService ipcService, File ipcConfigFile) { + public MXBeanConnectionPoolImpl(File binPath, UserNameUtil userNameUtil, AgentIPCService ipcService) { this(new ConnectorCreator(), binPath, new ProcessUserInfoBuilder(new ProcDataSource(), userNameUtil), - ipcService, ipcConfigFile, new FileSystemUtils()); + ipcService, new FileSystemUtils()); } MXBeanConnectionPoolImpl(ConnectorCreator connectorCreator, File binPath, ProcessUserInfoBuilder userInfoBuilder, - AgentIPCService ipcService, File ipcConfigFile, FileSystemUtils fsUtils) { + AgentIPCService ipcService, FileSystemUtils fsUtils) { this.pool = new HashMap<>(); this.creator = connectorCreator; this.binPath = binPath; this.userInfoBuilder = userInfoBuilder; this.ipcService = ipcService; - this.ipcConfigFile = ipcConfigFile; this.fsUtils = fsUtils; this.currentNewEntry = null; this.started = false; @@ -227,7 +224,8 @@ pool.put(pid, data); // Start agent proxy which will send the JMX service URL to the IPC server we created - AgentProxyClient proxy = creator.createAgentProxy(pid, username, binPath, ipcConfigFile, serverName); + File configFile = ipcService.getConfigurationFile(); + AgentProxyClient proxy = creator.createAgentProxy(pid, username, binPath, configFile, serverName); proxy.runProcess(); // Process completed when this returns // Block until we get a JMX service URL, or Exception
--- a/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java Tue Nov 15 18:18:31 2016 -0500 @@ -110,7 +110,8 @@ principal = mock(UserPrincipal.class); when(lookup.lookupPrincipalByName("Test")).thenReturn(principal); - pool = new MXBeanConnectionPoolImpl(creator, binDir, builder, ipcService, ipcConfigFile, fsUtils); + when(ipcService.getConfigurationFile()).thenReturn(ipcConfigFile); + pool = new MXBeanConnectionPoolImpl(creator, binDir, builder, ipcService, fsUtils); } @Test
--- a/agent/ipc/server/pom.xml Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/ipc/server/pom.xml Tue Nov 15 18:18:31 2016 -0500 @@ -77,6 +77,11 @@ </dependency> <dependency> <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-storage-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-agent-ipc-common</artifactId> <version>${project.version}</version> </dependency>
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/AgentIPCService.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/AgentIPCService.java Tue Nov 15 18:18:31 2016 -0500 @@ -36,6 +36,7 @@ package com.redhat.thermostat.agent.ipc.server; +import java.io.File; import java.io.IOException; import java.nio.file.attribute.UserPrincipal; @@ -90,4 +91,12 @@ */ void destroyServer(String name) throws IOException; + /** + * Returns the configuration file used by this IPC service. This file contains properties used + * to exchange information between the server-side and client-side IPC services. + * @return the configuration file + * @throws IOException if the configuration file cannot be obtained or the IPC service fails to start + */ + File getConfigurationFile() throws IOException; + }
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/ServerTransport.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/ServerTransport.java Tue Nov 15 18:18:31 2016 -0500 @@ -37,6 +37,7 @@ package com.redhat.thermostat.agent.ipc.server; import java.io.IOException; +import java.nio.file.attribute.UserPrincipal; import com.redhat.thermostat.agent.ipc.common.internal.IPCProperties; import com.redhat.thermostat.agent.ipc.common.internal.IPCType; @@ -45,7 +46,27 @@ * non-API interface mirroring AgentIPCService that provides IPC mechanism-specific * implementations of AgentIPCService's API methods */ -public interface ServerTransport extends AgentIPCService { +public interface ServerTransport { + + /** + * @see AgentIPCService#createServer(String, ThermostatIPCCallbacks) + */ + void createServer(String name, ThermostatIPCCallbacks callbacks) throws IOException; + + /** + * @see AgentIPCService#createServer(String, ThermostatIPCCallbacks, UserPrincipal) + */ + void createServer(String name, ThermostatIPCCallbacks callbacks, UserPrincipal owner) throws IOException; + + /** + * @see AgentIPCService#serverExists(String) + */ + boolean serverExists(String name) throws IOException; + + /** + * @see AgentIPCService#destroyServer(String) + */ + void destroyServer(String name) throws IOException; void start(IPCProperties props) throws IOException;
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/Activator.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/Activator.java Tue Nov 15 18:18:31 2016 -0500 @@ -43,13 +43,15 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; import com.redhat.thermostat.agent.ipc.server.AgentIPCService; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.common.MultipleServiceTracker.Action; +import com.redhat.thermostat.common.MultipleServiceTracker.DependencyProvider; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.shared.config.CommonPaths; +import com.redhat.thermostat.storage.core.WriterID; public class Activator implements BundleActivator { @@ -57,22 +59,25 @@ private ServerIPCPropertiesBuilder propBuilder; private AgentIPCServiceImpl ipcService; - private ServiceTracker tracker; + private MultipleServiceTracker tracker; private ServiceRegistration reg; - public void start(BundleContext context) throws Exception { + public void start(final BundleContext context) throws Exception { propBuilder = new ServerIPCPropertiesBuilder(context); - tracker = new ServiceTracker(context, CommonPaths.class.getName(), null) { + Class<?>[] deps = new Class<?>[] { CommonPaths.class, WriterID.class }; + tracker = new MultipleServiceTracker(context, deps, new Action() { + @Override - public Object addingService(ServiceReference reference) { - CommonPaths paths = (CommonPaths) super.addingService(reference); + public void dependenciesAvailable(DependencyProvider services) { + CommonPaths paths = (CommonPaths) services.get(CommonPaths.class); + WriterID writerID = (WriterID) services.get(WriterID.class); File propFile = paths.getUserIPCConfigurationFile(); - ipcService = new AgentIPCServiceImpl(propBuilder, context, propFile); + ipcService = new AgentIPCServiceImpl(propBuilder, context, propFile, writerID); reg = context.registerService(AgentIPCService.class.getName(), ipcService, null); - return paths; } + @Override - public void removedService(ServiceReference reference, Object service) { + public void dependenciesUnavailable() { if (reg != null) { try { ipcService.shutdown(); @@ -82,9 +87,8 @@ reg.unregister(); reg = null; } - super.removedService(reference, service); } - }; + }); tracker.open(); }
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImpl.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImpl.java Tue Nov 15 18:18:31 2016 -0500 @@ -38,6 +38,9 @@ import java.io.File; import java.io.IOException; +import java.nio.file.CopyOption; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.attribute.UserPrincipal; import java.util.HashMap; import java.util.Map; @@ -51,27 +54,35 @@ import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.ipc.server.ServerTransport; import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks; +import com.redhat.thermostat.storage.core.WriterID; class AgentIPCServiceImpl implements AgentIPCService { + static final String RUNTIME_IPC_CONFIG_PREFIX = "thermostat-ipc.properties."; + private final ServerIPCPropertiesBuilder propBuilder; private final ServiceTracker transportTracker; // Access/modification of this field should by synchronized private final Map<IPCType, ServerTransport> transports; + // IPC configuration residing in USER_THERMOSTAT_HOME private final File propFile; + private final WriterID writerID; private final FileHelper helper; private ServerTransport transport; private IPCProperties props; private boolean started; - AgentIPCServiceImpl(ServerIPCPropertiesBuilder propBuilder, BundleContext context, File propFile) { - this(propBuilder, context, propFile, new FileHelper()); + AgentIPCServiceImpl(ServerIPCPropertiesBuilder propBuilder, BundleContext context, File propFile, + WriterID writerID) { + this(propBuilder, context, propFile, writerID, new FileHelper()); } - AgentIPCServiceImpl(ServerIPCPropertiesBuilder propBuilder, BundleContext context, File propFile, FileHelper helper) { + AgentIPCServiceImpl(ServerIPCPropertiesBuilder propBuilder, BundleContext context, File propFile, + WriterID writerID, FileHelper helper) { this.propBuilder = propBuilder; this.propFile = propFile; + this.writerID = writerID; this.transports = new HashMap<>(); this.helper = helper; this.started = false; @@ -171,7 +182,23 @@ IPCConfigurationWriter writer = helper.getConfigurationWriter(propFile); writer.write(); } - return propBuilder.getProperties(propFile); + + // Copy read-only copy of IPC properties file to a world-readable location + String destDirPath = helper.getSystemProperty("java.io.tmpdir"); + if (destDirPath == null) { + throw new IOException("Required system property \"java.io.tmpdir\" is not defined"); + } + File destDir = helper.getFile(destDirPath); + + // Append agent ID to IPC config filename + String filename = RUNTIME_IPC_CONFIG_PREFIX.concat(writerID.getWriterID()); + File runtimeIpcConfig = helper.getFile(destDir, filename); + runtimeIpcConfig.deleteOnExit(); + + // Copy config file to destination + helper.copy(propFile.toPath(), runtimeIpcConfig.toPath()); + + return propBuilder.getProperties(runtimeIpcConfig); } // Helper class for testing purposes @@ -182,6 +209,18 @@ IPCConfigurationWriter getConfigurationWriter(File configFile) { return new IPCConfigurationWriter(configFile); } + String getSystemProperty(String key) { + return System.getProperty(key); + } + File getFile(File parent, String name) { + return new File(parent, name); + } + File getFile(String path) { + return new File(path); + } + Path copy(Path src, Path dst, CopyOption... options) throws IOException { + return Files.copy(src, dst, options); + } } // For testing purposes only @@ -192,4 +231,13 @@ } } + @Override + public File getConfigurationFile() throws IOException { + // Start the service if not already started + if (!started) { + startService(); + } + return props.getPropertiesFile(); + } + }
--- a/agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/ActivatorTest.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/ActivatorTest.java Tue Nov 15 18:18:31 2016 -0500 @@ -46,6 +46,7 @@ import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.shared.config.CommonPaths; +import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.testutils.StubBundleContext; public class ActivatorTest { @@ -70,6 +71,8 @@ CommonPaths paths = mock(CommonPaths.class); context.registerService(CommonPaths.class, paths, null); + WriterID writerID = mock(WriterID.class); + context.registerService(WriterID.class, writerID, null); Activator activator = new Activator(); @@ -78,7 +81,7 @@ activator.stop(context); assertEquals(0, context.getServiceListeners().size()); - assertEquals(1, context.getAllServices().size()); + assertEquals(2, context.getAllServices().size()); } @Test
--- a/agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImplTest.java Tue Nov 15 15:59:46 2016 -0500 +++ b/agent/ipc/server/src/test/java/com/redhat/thermostat/agent/ipc/server/internal/AgentIPCServiceImplTest.java Tue Nov 15 18:18:31 2016 -0500 @@ -47,6 +47,7 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.nio.file.attribute.UserPrincipal; import java.util.Map; @@ -59,17 +60,25 @@ import com.redhat.thermostat.agent.ipc.server.ServerTransport; import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks; import com.redhat.thermostat.agent.ipc.server.internal.AgentIPCServiceImpl.FileHelper; +import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.testutils.StubBundleContext; public class AgentIPCServiceImplTest { private static final String SERVER_NAME = "test"; + private static final String TMPDIR = "/path/to/tmp"; + private static final String AGENT_ID = "myAgentId"; private ServerTransport transport; private IPCProperties props; private FileHelper helper; private IPCConfigurationWriter writer; - private File propFile; + private File userPropFile; + private File tmpdirFile; + private File runtimePropFile; + private Path userPropPath; + private Path runtimePropPath; + private WriterID writerID; private ServerIPCPropertiesBuilder propBuilder; private StubBundleContext context; @@ -78,14 +87,25 @@ context = new StubBundleContext(); transport = mock(ServerTransport.class); when(transport.getType()).thenReturn(IPCType.UNKNOWN); - propFile = mock(File.class); + userPropFile = mock(File.class); + userPropPath = mock(Path.class); + when(userPropFile.toPath()).thenReturn(userPropPath); propBuilder = mock(ServerIPCPropertiesBuilder.class); props = mock(IPCProperties.class); when(props.getType()).thenReturn(IPCType.UNKNOWN); - when(propBuilder.getProperties(propFile)).thenReturn(props); + runtimePropFile = mock(File.class); + when(propBuilder.getProperties(runtimePropFile)).thenReturn(props); + runtimePropPath = mock(Path.class); + when(runtimePropFile.toPath()).thenReturn(runtimePropPath); + writerID = mock(WriterID.class); + when(writerID.getWriterID()).thenReturn(AGENT_ID); helper = mock(FileHelper.class); writer = mock(IPCConfigurationWriter.class); - when(helper.getConfigurationWriter(propFile)).thenReturn(writer); + when(helper.getConfigurationWriter(userPropFile)).thenReturn(writer); + when(helper.getSystemProperty("java.io.tmpdir")).thenReturn(TMPDIR); + tmpdirFile = mock(File.class); + when(helper.getFile(TMPDIR)).thenReturn(tmpdirFile); + when(helper.getFile(tmpdirFile, AgentIPCServiceImpl.RUNTIME_IPC_CONFIG_PREFIX + AGENT_ID)).thenReturn(runtimePropFile); } @Test @@ -102,9 +122,38 @@ verify(writer).write(); verify(transport).createServer(SERVER_NAME, callbacks); } + + @Test + public void testStartCreatesRuntimePropertyFile() throws Exception { + context.registerService(ServerTransport.class.getName(), transport, null); + AgentIPCServiceImpl service = createService(); + ThermostatIPCCallbacks callbacks = mock(ThermostatIPCCallbacks.class); + + assertFalse(service.isStarted()); + service.createServer(SERVER_NAME, callbacks); + assertTrue(service.isStarted()); + + verify(helper).getSystemProperty("java.io.tmpdir"); + verify(helper).getFile(TMPDIR); + verify(helper).getFile(tmpdirFile, AgentIPCServiceImpl.RUNTIME_IPC_CONFIG_PREFIX + AGENT_ID); + verify(helper).copy(userPropPath, runtimePropPath); + verify(runtimePropFile).deleteOnExit(); + } + + @Test(expected=IOException.class) + public void testUndefinedTmpdirThrowsException() throws Exception { + when(helper.getSystemProperty("java.io.tmpdir")).thenReturn(null); + + context.registerService(ServerTransport.class.getName(), transport, null); + AgentIPCServiceImpl service = createService(); + ThermostatIPCCallbacks callbacks = mock(ThermostatIPCCallbacks.class); + + assertFalse(service.isStarted()); + service.createServer(SERVER_NAME, callbacks); + } private AgentIPCServiceImpl createService() { - return new AgentIPCServiceImpl(propBuilder, context, propFile, helper); + return new AgentIPCServiceImpl(propBuilder, context, userPropFile, writerID, helper); } @Test @@ -141,7 +190,7 @@ public void testCreateServerFileExists() throws Exception { context.registerService(ServerTransport.class.getName(), transport, null); AgentIPCServiceImpl service = createService(); - when(helper.configFileExists(propFile)).thenReturn(true); + when(helper.configFileExists(userPropFile)).thenReturn(true); ThermostatIPCCallbacks callbacks = mock(ThermostatIPCCallbacks.class); assertFalse(service.isStarted());
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java Tue Nov 15 15:59:46 2016 -0500 +++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java Tue Nov 15 18:18:31 2016 -0500 @@ -36,6 +36,7 @@ package com.redhat.thermostat.vm.byteman.agent.internal; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.ServerSocket; @@ -47,9 +48,9 @@ import org.jboss.byteman.agent.install.Install; +import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.utils.ProcessChecker; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.shared.config.CommonPaths; import com.sun.tools.attach.AgentInitializationException; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; @@ -72,16 +73,16 @@ }; private final BtmInstallHelper installer; private final ProcessChecker processChecker; - private final CommonPaths paths; + private final AgentIPCService ipcService; - BytemanAttacher(CommonPaths paths) { - this(new BtmInstallHelper(), new ProcessChecker(), paths); + BytemanAttacher(AgentIPCService ipcProps) { + this(new BtmInstallHelper(), new ProcessChecker(), ipcProps); } - BytemanAttacher(BtmInstallHelper installer, ProcessChecker processChecker, CommonPaths paths) { + BytemanAttacher(BtmInstallHelper installer, ProcessChecker processChecker, AgentIPCService ipcService) { this.installer = installer; this.processChecker = processChecker; - this.paths = paths; + this.ipcService = ipcService; } @@ -122,11 +123,12 @@ // Note: Setting properties will not work if they don't start with the // byteman prefix. Namely, "org.jboss.byteman." - private String[] buildBytemanInstallProps(VmSocketIdentifier sockIdentifier, int port) { + private String[] buildBytemanInstallProps(VmSocketIdentifier sockIdentifier, int port) throws IOException { List<String> properties = new ArrayList<>(); properties.addAll(Arrays.asList(BYTEMAN_STATIC_INSTALL_PROPS)); String socketNameProperty = THERMOSTAT_HELPER_SOCKET_NAME_PROPERTY + "=" + sockIdentifier.getName(); - String ipcSocketDirProperty = THERMOSTAT_IPC_CONFIG_NAME_PROPERTY + "=" + paths.getUserIPCConfigurationFile().getAbsolutePath(); + File ipcConfig = ipcService.getConfigurationFile(); + String ipcSocketDirProperty = THERMOSTAT_IPC_CONFIG_NAME_PROPERTY + "=" + ipcConfig.getAbsolutePath(); String agentPortProperty = BYTEMAN_AGENT_PORT_PROPERTY + "=" + Integer.valueOf(port).toString(); properties.add(socketNameProperty); properties.add(ipcSocketDirProperty);
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java Tue Nov 15 15:59:46 2016 -0500 +++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java Tue Nov 15 18:18:31 2016 -0500 @@ -134,23 +134,23 @@ protected void bindCommonPaths(CommonPaths paths) { attachManager.setPaths(paths); - BytemanAttacher bmAttacher = new BytemanAttacher(paths); - attachManager.setAttacher(bmAttacher); } protected void unbindCommonPaths(CommonPaths paths) { // helper jars don't strictly need unsetting so we don't // call setPaths(null) - attachManager.setAttacher(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) {
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java Tue Nov 15 15:59:46 2016 -0500 +++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java Tue Nov 15 18:18:31 2016 -0500 @@ -61,9 +61,9 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks; import com.redhat.thermostat.agent.utils.ProcessChecker; -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.agent.internal.BytemanAgentAttachManager.FileSystemUtils; @@ -280,7 +280,7 @@ @SuppressWarnings("unchecked") private BytemanAttacher getFailureAttacher() throws Exception { - CommonPaths paths = mock(CommonPaths.class); + AgentIPCService ipcService = mock(AgentIPCService.class); BtmInstallHelper failInstaller = mock(BtmInstallHelper.class); when(failInstaller.install(any(String.class), any(boolean.class), @@ -288,9 +288,9 @@ any(String.class), any(int.class), any(String[].class))).thenThrow(IOException.class); - when(paths.getUserIPCConfigurationFile()).thenReturn(mock(File.class)); + when(ipcService.getConfigurationFile()).thenReturn(mock(File.class)); ProcessChecker processChecker = mock(ProcessChecker.class); - BytemanAttacher failAttacher = new BytemanAttacher(failInstaller, processChecker, paths); + BytemanAttacher failAttacher = new BytemanAttacher(failInstaller, processChecker, ipcService); return failAttacher; }
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java Tue Nov 15 15:59:46 2016 -0500 +++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java Tue Nov 15 18:18:31 2016 -0500 @@ -55,8 +55,8 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.utils.ProcessChecker; -import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.BtmInstallHelper; import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.InstallResult; @@ -74,7 +74,7 @@ System.err.println("Usage: java BytemanAttacherTest <PID_OF_JVM>"); System.exit(1); } - BytemanAttacher attacher = new BytemanAttacher(mock(CommonPaths.class)); + BytemanAttacher attacher = new BytemanAttacher(mock(AgentIPCService.class)); BytemanAgentInfo info = attacher.attach("barVmId", Integer.parseInt(args[0]), "fooAgent"); if (info != null) { System.out.println("Byteman agent attached successfully"); @@ -84,17 +84,17 @@ } } - private CommonPaths paths; + private AgentIPCService ipcService; private String filePath; private ProcessChecker processChecker; @Before - public void setup() { + public void setup() throws Exception { filePath = "/path/to/run/data"; - paths = mock(CommonPaths.class); + ipcService = mock(AgentIPCService.class); File mockFile = mock(File.class); when(mockFile.getAbsolutePath()).thenReturn(filePath); - when(paths.getUserIPCConfigurationFile()).thenReturn(mockFile); + when(ipcService.getConfigurationFile()).thenReturn(mockFile); processChecker = mock(ProcessChecker.class); when(processChecker.exists(anyInt())).thenReturn(false); @@ -106,7 +106,7 @@ when(installer.install(any(String.class), any(boolean.class), any(boolean.class), any(String.class), any(int.class), any(String[].class))) .thenReturn(new InstallResult(8888, true)); ArgumentCaptor<String[]> propsCaptor = ArgumentCaptor.forClass(String[].class); - BytemanAttacher attacher = new BytemanAttacher(installer, processChecker, paths); + BytemanAttacher attacher = new BytemanAttacher(installer, processChecker, ipcService); attacher.attach("testVmId", 9999, "fooAgent"); verify(installer).install(eq(Integer.toString(9999)), eq(true), eq(false), eq((String)null), any(int.class), propsCaptor.capture()); Map<String, String> properties = buildMapFromStringProps(propsCaptor.getValue()); @@ -134,7 +134,7 @@ BtmInstallHelper installer = mock(BtmInstallHelper.class); when(installer.install(any(String.class), any(boolean.class), any(boolean.class), any(String.class), any(int.class), any(String[].class))) .thenReturn(new InstallResult(port, true)); - BytemanAttacher attacher = new BytemanAttacher(installer, mock(ProcessChecker.class), paths); + BytemanAttacher attacher = new BytemanAttacher(installer, mock(ProcessChecker.class), ipcService); int somePid = 3222; BytemanAgentInfo info = attacher.attach("someVmId", somePid, "someAgent"); @@ -162,7 +162,7 @@ IOException ioe = new IOException(exceptionMsg); when(installer.install(any(String.class), any(Boolean.class), any(Boolean.class), any(String.class), any(Integer.class), any(String[].class))).thenThrow(ioe); - BytemanAttacher attacher = new BytemanAttacher(installer, processChecker, paths); + BytemanAttacher attacher = new BytemanAttacher(installer, processChecker, ipcService); BytemanAgentInfo info = attacher.attach("someVmId", -1, "someAgent"); assertNotNull(info); assertTrue(info.isAttachFailedNoSuchProcess());
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java Tue Nov 15 15:59:46 2016 -0500 +++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java Tue Nov 15 18:18:31 2016 -0500 @@ -57,6 +57,7 @@ import org.junit.Test; 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; @@ -216,8 +217,17 @@ BytemanRequestReceiver receiver = new BytemanRequestReceiver(attachManager); CommonPaths paths = mock(CommonPaths.class); receiver.bindCommonPaths(paths); + verify(attachManager).setPaths(paths); + } + + @Test + public void testBindAgentIPCService() { + BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class); + BytemanRequestReceiver receiver = new BytemanRequestReceiver(attachManager); + AgentIPCService ipcService = mock(AgentIPCService.class); + receiver.bindAgentIpcService(ipcService); + verify(attachManager).setIpcManager(any(IPCEndpointsManager.class)); verify(attachManager).setAttacher(any(BytemanAttacher.class)); - verify(attachManager).setPaths(paths); } @SuppressWarnings("unchecked")