Mercurial > hg > thermostat
changeset 2568:b98beac5559c
refactor - move all os-specific code into a new package
This patch moves most os-specific code to a new package, com.redhat.thermostat.common.portability.
Most of the remaining code is Linux code that references the /proc filesystem; this code
will be addressed in a separate patch.
Reviewed by: ebaron
Review thread: http://icedtea.classpath.org/pipermail/thermostat/2017-January/021916.html
line wrap: on
line diff
--- a/README.api Fri Jan 20 10:48:09 2017 -0500 +++ b/README.api Mon Jan 23 10:11:31 2017 -0500 @@ -7,9 +7,7 @@ - com.redhat.thermostat.agent.command - com.redhat.thermostat.agent.config - com.redhat.thermostat.agent.utils - - com.redhat.thermostat.agent.utils.hostname - com.redhat.thermostat.agent.utils.management - - com.redhat.thermostat.agent.utils.username - com.redhat.thermostat.annotations - com.redhat.thermostat.backend - com.redhat.thermostat.client.cli @@ -27,6 +25,7 @@ - com.redhat.thermostat.common.command - com.redhat.thermostat.common.config - com.redhat.thermostat.common.model + - com.redhat.thermostat.common.portability - com.redhat.thermostat.common.ssl - com.redhat.thermostat.common.tools - com.redhat.thermostat.common.utils
--- a/agent/core/Makefile Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -CC = gcc -JAVAH = javah -MYCFLAGS = -c -Wall $(EXTRA_CFLAGS) -MYLDFLAGS = -shared $(EXTRA_CFLAGS) -COPY = cp -a - -CLASSPATH = target/classes/ -TARGET_DIR = target - -ifeq ($(OS),Windows_NT) - JNI_PLATFORM = win32 - SO_PREFIX = - SO_SUFFIX = .dll -else - JNI_PLATFORM = linux - SO_PREFIX = lib - SO_SUFFIX = .so - MYCFLAGS += -fPIC - MYLDFLAGS += -fPIC -endif - -INCLUDE = -I $(TARGET_DIR) -I "$(JAVA_HOME)/include/" -I "$(JAVA_HOME)/include/$(JNI_PLATFORM)" - -HOSTNAME_SOURCES = src/main/native/HostName.c -HOSTNAME_TARGET = $(TARGET_DIR)/HostName.c -HOSTNAME_OBJECTS = $(HOSTNAME_TARGET:.c=.o) -HOSTNAME_EXECUTABLE = $(SO_PREFIX)HostNameWrapper$(SO_SUFFIX) - -USERNAME_SOURCES = src/main/native/UserNameUtilImpl.c -USERNAME_TARGET = $(TARGET_DIR)/UserNameUtilImpl.c -USERNAME_OBJECTS = $(USERNAME_TARGET:.c=.o) -USERNAME_EXECUTABLE = $(SO_PREFIX)UserNameUtilWrapper$(SO_SUFFIX) - -WINHELPER_SOURCES = src/main/native/WindowsHelperImpl.c -WINHELPER_TARGET = $(TARGET_DIR)/WindowsHelperImpl.c -WINHELPER_OBJECTS = $(WINHELPER_TARGET:.c=.o) -WINHELPER_EXECUTABLE = $(SO_PREFIX)WindowsHelperWrapper$(SO_SUFFIX) - -EXECUTABLES = $(HOSTNAME_EXECUTABLE) $(USERNAME_EXECUTABLE) - -.PHONY: -JNI_LIST = com.redhat.thermostat.agent.utils.hostname.HostName\ - com.redhat.thermostat.utils.username.internal.UserNameUtilImpl - -ifeq ($(OS),Windows_NT) - EXECUTABLES += $(WINHELPER_EXECUTABLE) - JNI_LIST += com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl -endif - -$(JNI_LIST): - $(JAVAH) -force -classpath $(CLASSPATH) -d $(TARGET_DIR) $(JNI_LIST) - -all: $(JNI_LIST) init $(HOSTNAME_SOURCES) $(USERNAME_SOURCES) $(WINHELPER_SOURCES) $(EXECUTABLES) - -.PHONY: -init: - $(COPY) $(HOSTNAME_SOURCES) $(HOSTNAME_TARGET) - $(COPY) $(USERNAME_SOURCES) $(USERNAME_TARGET) - $(COPY) $(WINHELPER_SOURCES) $(WINHELPER_TARGET) - -$(HOSTNAME_EXECUTABLE): $(HOSTNAME_OBJECTS) - $(CC) $(MYLDFLAGS) $(LDFLAGS) $(HOSTNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@ - -$(USERNAME_EXECUTABLE): $(USERNAME_OBJECTS) - $(CC) $(MYLDFLAGS) $(LDFLAGS) $(USERNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@ - -$(WINHELPER_EXECUTABLE): $(WINHELPER_OBJECTS) - $(CC) $(MYLDFLAGS) $(LDFLAGS) $(WINHELPER_OBJECTS) $(PLATFORM_LIBS) -l psapi -o $(TARGET_DIR)/$@ - -.c.o: - $(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@ - -.cpp.o: - $(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@ - - -clean-lib: - rm -f $(TARGET_DIR)/$(HOSTNAME_EXECUTABLE) - rm -f $(TARGET_DIR)/$(USERNAME_EXECUTABLE) - rm -f $(TARGET_DIR)/$(WINHELPER_EXECUTABLE) - -clean-obj: - rm -f $(HOSTNAME_OBJECTS) $(HOSTNAME_TARGET) - rm -f $(USERNAME_OBJECTS) $(USERNAME_TARGET) - rm -f $(WINHELPER_OBJECTS) $(WINHELPER_TARGET) - -clean: clean-obj clean-lib -
--- a/agent/core/pom.xml Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/core/pom.xml Mon Jan 23 10:11:31 2017 -0500 @@ -50,37 +50,6 @@ <name>Thermostat Agent Core</name> - <profiles> - <profile> - <id>default</id> - <activation> - <activeByDefault>true</activeByDefault> - </activation> - </profile> - - <profile> - <id>linux</id> - <activation> - <os><family>Unix</family></os> - </activation> - <properties> - <platform.libs></platform.libs> - </properties> - </profile> - - <profile> - <id>windows</id> - <activation> - <os><family>Windows</family></os> - </activation> - <properties> - <platform.libs>-lws2_32</platform.libs> - <sharedlib.prefix></sharedlib.prefix> - <sharedlib.suffix>.dll</sharedlib.suffix> - </properties> - </profile> - </profiles> - <dependencies> <dependency> <groupId>junit</groupId> @@ -105,6 +74,11 @@ </dependency> <dependency> <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-portability</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-launcher</artifactId> <version>${project.version}</version> </dependency> @@ -145,21 +119,16 @@ <Bundle-SymbolicName>com.redhat.thermostat.agent.core</Bundle-SymbolicName> <Bundle-Activator>com.redhat.thermostat.agent.internal.Activator</Bundle-Activator> <Export-Package> - com.redhat.thermostat.agent, - com.redhat.thermostat.agent.config, - com.redhat.thermostat.agent.utils, - com.redhat.thermostat.agent.utils.hostname, - com.redhat.thermostat.agent.utils.linux, - com.redhat.thermostat.agent.utils.management, - com.redhat.thermostat.agent.utils.username, - com.redhat.thermostat.agent.utils.windows, - com.redhat.thermostat.backend, + com.redhat.thermostat.agent, + com.redhat.thermostat.agent.config, + com.redhat.thermostat.agent.utils, + com.redhat.thermostat.agent.utils.management, + com.redhat.thermostat.backend </Export-Package> <Private-Package> com.redhat.thermostat.agent.internal, com.redhat.thermostat.backend.internal, - com.redhat.thermostat.utils.management.internal, - com.redhat.thermostat.utils.username.internal, + com.redhat.thermostat.utils.management.internal </Private-Package> <!-- Do not autogenerate uses clauses in Manifests --> <_nouses>true</_nouses> @@ -176,38 +145,9 @@ </systemPropertyVariables> </configuration> </plugin> - - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>exec-maven-plugin</artifactId> - <executions> - <execution> - <phase>compile</phase> - <goals> - <goal>exec</goal> - </goals> - </execution> - </executions> - <configuration> - <executable>make</executable> - <arguments> - <argument>all</argument> - <argument>CC=${c.compiler}</argument> - <argument>SO_PREFIX=${sharedlib.prefix}</argument> - <argument>SO_SUFFIX=${sharedlib.suffix}</argument> - <argument>EXTRA_CFLAGS=${cflags}</argument> - <argument>JNI_PLATFORM=${jni.platform}</argument> - <argument>PLATFORM_LIBS=${platform.libs}</argument> - </arguments> - <systemProperties> - <systemProperty> - <key>JAVA_HOME</key> - <value>${java.home}</value> - </systemProperty> - </systemProperties> - </configuration> - </plugin> + </plugins> + <pluginManagement> <plugins> <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.--> @@ -227,7 +167,7 @@ </goals> </pluginExecutionFilter> <action> - <ignore></ignore> + <ignore/> </action> </pluginExecution> </pluginExecutions>
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java Mon Jan 23 10:11:31 2017 -0500 @@ -50,7 +50,7 @@ import com.redhat.thermostat.agent.config.AgentConfigsUtils; import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; +import com.redhat.thermostat.common.portability.UserNameUtil; import com.redhat.thermostat.common.MultipleServiceTracker; import com.redhat.thermostat.common.MultipleServiceTracker.Action; import com.redhat.thermostat.common.MultipleServiceTracker.DependencyProvider; @@ -62,7 +62,6 @@ import com.redhat.thermostat.utils.management.internal.AgentProxyFilter; import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolControl; import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl; -import com.redhat.thermostat.utils.username.internal.UserNameUtilImpl; public class Activator implements BundleActivator { @@ -75,10 +74,6 @@ @Override public void start(final BundleContext context) throws Exception { - // No deps, register immediately - UserNameUtilImpl usernameUtil = new UserNameUtilImpl(); - context.registerService(UserNameUtil.class, usernameUtil, null); - // Track common paths separately and register storage credentials quickly // We need to do this since otherwise no storage credentials will be // available by the time they're used in DbService
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/ProcessChecker.java Fri Jan 20 10:48:09 2017 -0500 +++ /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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils; - -import java.io.File; -/** - * Utility for checking whether a process exists or not. - * - * Implementation note: This is Linux specific. - * - */ -public class ProcessChecker { - - public boolean exists(int pid) { - File procFile = mapToFile(pid); - return procFile.exists(); - } - - // testing-hook - File mapToFile(int pid) { - return new File("/proc/" + pid); - } - -}
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/SysConf.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils; - -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; -import com.redhat.thermostat.shared.config.OS; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -/** - * A wrapper over POSIX's sysconf. - * <p> - * Implementation notes: uses {@code getconf(1)} - */ -public class SysConf { - - private SysConf() { - /* do not initialize */ - } - - public static long getClockTicksPerSecond() { - return OS.IS_LINUX ? getLinuxClockTicksPerSecond() : getWindowsClockTicksPerSecond(); - } - - private static long getWindowsClockTicksPerSecond() { - return WindowsHelperImpl.INSTANCE.getClockTicksPerSecond(); - } - - public static long getLinuxClockTicksPerSecond() { - String ticks = sysConf("CLK_TCK"); - try { - return Long.valueOf(ticks); - } catch (NumberFormatException nfe) { - return 0; - } - } - - private static String sysConf(String arg) { - try { - Process process = Runtime.getRuntime().exec(new String[] { "getconf", arg }); - int result = process.waitFor(); - if (result != 0) { - return null; - } - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { - return reader.readLine(); - } - } catch (IOException | InterruptedException e) { - return null; - } - } -} -
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/hostname/HostName.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils.hostname; - -import com.redhat.thermostat.shared.config.NativeLibraryResolver; - -/** - * Finds the current host name without doing a DNS lookup - */ -public class HostName { - - static { - String lib = NativeLibraryResolver.getAbsoluteLibraryPath("HostNameWrapper"); - System.load(lib); - } - - public static String getLocalHostName() { - return getHostName(); - } - - private static native String getHostName(); -} -
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/linux/ProcDataSource.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils.linux; - -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; - -/** - * Wrapper for files under {@code /proc/}. See proc(5) for details about this. - */ -public class ProcDataSource { - - private static final String LOAD_FILE = "/proc/loadavg"; - private static final String STAT_FILE = "/proc/stat"; - private static final String MEMINFO_FILE = "/proc/meminfo"; - private static final String CPUINFO_FILE = "/proc/cpuinfo"; - - private static final String PID_ENVIRON_FILE = "/proc/${pid}/environ"; - private static final String PID_IO_FILE = "/proc/${pid}/io"; - private static final String PID_STAT_FILE = "/proc/${pid}/stat"; - private static final String PID_STATUS_FILE = "/proc/${pid}/status"; - - /** - * Returns a reader for /proc/cpuinfo - */ - public Reader getCpuInfoReader() throws IOException { - return new FileReader(CPUINFO_FILE); - } - - /** - * Returns a reader for /proc/loadavg - */ - public Reader getCpuLoadReader() throws IOException { - return new FileReader(LOAD_FILE); - } - - /** - * Returns a reader for /proc/stat. Kernel/System statistics. - */ - public Reader getStatReader() throws IOException { - return new FileReader(STAT_FILE); - } - - /** - * Returns a reader for /proc/meminfo - */ - public Reader getMemInfoReader() throws IOException { - return new FileReader(MEMINFO_FILE); - } - - /** - * Returns a reader for /proc/$PID/environ - */ - public Reader getEnvironReader(int pid) throws IOException { - return new FileReader(getPidFile(PID_ENVIRON_FILE, pid)); - } - - /** - * Returns a reader for /proc/$PID/io - */ - public Reader getIoReader(int pid) throws IOException { - return new FileReader(getPidFile(PID_IO_FILE, pid)); - } - - /** - * Returns a reader for /proc/$PID/stat - */ - public Reader getStatReader(int pid) throws IOException { - return new FileReader(getPidFile(PID_STAT_FILE, pid)); - } - - /** - * Returns a reader for /proc/$PID/status - */ - public Reader getStatusReader(int pid) throws IOException { - return new FileReader(getPidFile(PID_STATUS_FILE, pid)); - } - - private String getPidFile(String fileName, int pid) { - return fileName.replace("${pid}", Integer.toString(pid)); - } - -} -
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/username/UserNameLookupException.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils.username; - -/** - * - * Thrown on user name lookup error. - * - * @see UserNameUtil - */ -@SuppressWarnings("serial") -public class UserNameLookupException extends Exception { - - public UserNameLookupException(Throwable cause) { - super(cause); - } -} -
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/username/UserNameUtil.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils.username; - -import com.redhat.thermostat.annotations.Service; - -/** - * Utility to query the operating system for a user name. - */ -@Service -public interface UserNameUtil { - - /** - * Gets the user name corresponding to the provided UID. - * - * @param uid - * The UID whose name to return. - * @throws UserNameLookupException - * If an error occurred during retrieval of the user name. - * @return The user name if found. null if no such UID exists. - */ - String getUserName(long uid) throws UserNameLookupException; - -} -
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/username/package-info.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +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 - * <http://www.gnu.org/licenses/>. - * - * 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. - */ - - -/** - * Utilities to help with username lookups - */ -package com.redhat.thermostat.agent.utils.username;
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/windows/WindowsHelperImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,260 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils.windows; - -import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.shared.config.NativeLibraryResolver; -import com.redhat.thermostat.shared.config.OS; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Logger; - -/** - * Utility class to access Windows native code - */ -public class WindowsHelperImpl { - - private static final Logger logger = LoggingUtils.getLogger(WindowsHelperImpl.class); - - /* - // from MemoryStatusEx (8 values) - DWORD dwMemoryLoad; - DWORDLONG ullTotalPhys; - DWORDLONG ullAvailPhys; - DWORDLONG ullTotalPageFile; - DWORDLONG ullAvailPageFile; - DWORDLONG ullTotalVirtual; - DWORDLONG ullAvailVirtual; - DWORDLONG ullAvailExtendedVirtual; - - // from PERFORMANCE_INFORMATION (13 values) - SIZE_T CommitTotal; - SIZE_T CommitLimit; - SIZE_T CommitPeak; - SIZE_T PhysicalTotal; - SIZE_T PhysicalAvailable; - SIZE_T SystemCache; - SIZE_T KernelTotal; - SIZE_T KernelPaged; - SIZE_T KernelNonpaged; - SIZE_T PageSize; - DWORD HandleCount; - DWORD ProcessCount; - DWORD ThreadCount; - */ - - static { - if (OS.IS_WINDOWS) { - String lib = NativeLibraryResolver.getAbsoluteLibraryPath("WindowsHelperWrapper"); - try { - System.load(lib); - INSTANCE = new WindowsHelperImpl(); - } catch (UnsatisfiedLinkError e) { - logger.severe("Could not load WindowsHelperImpl DLL:" + lib); - INSTANCE = null; - // do not throw here, because you'll get a NoClassDefFound thrown when running other tests that Mock this class - } - } else { - INSTANCE = null; - } - } - - public static class MemoryStat { - - private final long timeStamp; - private final long total; - private final long free; - private final long buffers; - private final long cached; - private final long swapTotal; - private final long swapFree; - private final long commitLimit; - - - public MemoryStat() { - final long[] info = INSTANCE.getMemoryInfo(); - this.timeStamp = System.currentTimeMillis(); - this.total = info[1]; - this.free = info[2]; - this.buffers = 0; - this.cached = 0; - this.swapTotal = 3; - this.swapFree = 4; - this.commitLimit = 0; - // TODO - buffers, cached and commitLimit - } - - public MemoryStat(long timeStamp, long total, long free, long buffers, long cached, long swapTotal, long swapFree, long commitLimit) { - this.timeStamp = timeStamp; - this.total = total; - this.free = free; - this.buffers = buffers; - this.cached = cached; - this.swapTotal = swapTotal; - this.swapFree = swapFree; - this.commitLimit = commitLimit; - } - - public long getTimeStamp() { - return timeStamp; - } - public long getTotal() { - return total; - } - public long getFree() { - return free; - } - public long getBuffers() { - return buffers; - } - public long getCached() { - return cached; - } - public long getSwapTotal() { - return swapTotal; - } - public long getSwapFree() { - return swapFree; - } - public long getCommitLimit() { - return commitLimit; - } - } - - public static WindowsHelperImpl INSTANCE; - - private WindowsHelperImpl() { - } - // local host-wide information - - public String getHostName() { - return getHostName0(true); - } - - public String getOSName() { - return System.getProperty("os.name"); - } - - public String getOSVersion() { - final long info[] = new long[3]; // major, minor, build - getOSVersion0(info); - return "" + info[0] + "." + info[1] + " (Build " + info[2] + ")"; - } - - public String getCPUModel() { - return getCPUString0(); - } - - public int getCPUCount() { - return getCPUCount0(); - } - - public long getTotalMemory() { - final long info[] = getMemoryInfo(); - return info[1]; // totalPhysical - } - - // local process-specific information - public String getUserName(int pid) { - return getUserName0(pid,true); - } - - public int getUid(int pid) { - return getUid0(pid); - } - - public Map<String, String> getEnvironment(int pid) { - // the environment is returned as a 1D array of alternating env names and values - final String[] envArray = getEnvironment0(pid); - if (envArray == null || envArray.length == 0) { - return Collections.emptyMap(); - } - - if (envArray.length % 2 != 0) { - throw new AssertionError("environment array length not even"); - } - - final Map<String, String> env = new HashMap<>(envArray.length/2); - for (int i = 0; i < envArray.length / 2; i++) { - env.put(envArray[i * 2], envArray[i * 2 + 1]); - } - return env; - } - - public long[] getProcessCPUInfo(int pid) { - final long[] info = new long[4]; - getProcessInfo0(pid, info); - return info; - } - - public long[] getProcessMemInfo(int pid) { - final long[] info = new long[4]; - getProcessInfo0(pid, info); - return info; - } - - - private long[] getMemoryInfo() { - final long[] mi = new long[8]; - getGlobalMemoryStatus0(mi); - return mi; - } - - private long[] getPerformanceInfo() { - final long[] mi = new long[13]; - getPerformanceInfo0(mi); - return mi; - } - - public long getClockTicksPerSecond() { - return getClockTicksPerSecond0(); - } - - private static native String getHostName0(boolean prependDomain); - private static native void getOSVersion0(long[] versionAndBuild); - private static native int getUid0(int pid); - private static native String getUserName0(int pid, boolean prependDomain); - private static native String[] getEnvironment0(int pid); - private static native boolean getGlobalMemoryStatus0(long[] info); - private static native boolean getPerformanceInfo0(long[] info); - private static native boolean getProcessInfo0(int pid, long[] info); - private static native String getCPUString0(); - private static native int getCPUCount0(); - private static native long getClockTicksPerSecond0(); -}
--- a/agent/core/src/main/java/com/redhat/thermostat/backend/internal/VmMonitor.java Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/core/src/main/java/com/redhat/thermostat/backend/internal/VmMonitor.java Mon Jan 23 10:11:31 2017 -0500 @@ -48,7 +48,7 @@ import sun.jvmstat.monitor.MonitoredVm; import sun.jvmstat.monitor.VmIdentifier; -import com.redhat.thermostat.agent.utils.ProcessChecker; +import com.redhat.thermostat.common.portability.ProcessChecker; import com.redhat.thermostat.backend.VmUpdateListener; import com.redhat.thermostat.common.Pair; import com.redhat.thermostat.common.utils.LoggingUtils;
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/AgentProxyClient.java Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/AgentProxyClient.java Mon Jan 23 10:11:31 2017 -0500 @@ -40,6 +40,7 @@ import java.io.IOException; import com.redhat.thermostat.common.ExitStatus; +import com.redhat.thermostat.shared.config.OS; class AgentProxyClient { @@ -68,7 +69,9 @@ void runProcess() throws IOException, InterruptedException { // Start the agent proxy String serverPath = binPath + File.separator + SERVER_NAME; - String[] args = new String[] { serverPath, String.valueOf(pid), username, ipcConfigFile.getAbsolutePath(), serverName }; + String[] args = OS.IS_UNIX + ? new String[] { serverPath, String.valueOf(pid), username, ipcConfigFile.getAbsolutePath(), serverName } + : new String[] { "cmd", "/C", serverPath+".cmd", String.valueOf(pid), username, ipcConfigFile.getAbsolutePath(), serverName }; ProcessBuilder builder = new ProcessBuilder(args); builder.inheritIO(); Process proxy = procCreator.startProcess(builder);
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -59,12 +59,13 @@ import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.ipc.server.IPCMessage; import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.agent.utils.management.MXBeanConnection; import com.redhat.thermostat.agent.utils.management.MXBeanConnectionException; import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; -import com.redhat.thermostat.utils.management.internal.ProcessUserInfoBuilder.ProcessUserInfo; +import com.redhat.thermostat.common.portability.UserNameUtil; public class MXBeanConnectionPoolImpl implements MXBeanConnectionPoolControl, ThermostatIPCCallbacks { @@ -94,7 +95,7 @@ private boolean started; public MXBeanConnectionPoolImpl(File binPath, UserNameUtil userNameUtil, AgentIPCService ipcService) { - this(new ConnectorCreator(), binPath, new ProcessUserInfoBuilder(new ProcDataSource(), userNameUtil), + this(new ConnectorCreator(), binPath, ProcessUserInfo.createBuilder(new ProcDataSource(), userNameUtil), ipcService, new FileSystemUtils()); }
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/ProcessUserInfoBuilder.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.utils.management.internal; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.username.UserNameLookupException; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; -import com.redhat.thermostat.common.utils.LoggingUtils; - -/* - * FIXME: This class was copied from system-backend to avoid adding new API. - */ -class ProcessUserInfoBuilder { - - private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo(); - private static final String PROC_STATUS_UID = "Uid:"; - private static final Logger logger = LoggingUtils.getLogger(ProcessUserInfoBuilder.class); - private ProcDataSource source; - private UserNameUtil userNameUtil; - - ProcessUserInfoBuilder(ProcDataSource source, UserNameUtil userNameUtil) { - this.source = source; - this.userNameUtil = userNameUtil; - } - - static class ProcessUserInfo { - - private long uid; - private String username; - - ProcessUserInfo(long uid, String username) { - this.uid = uid; - this.username = username; - } - - ProcessUserInfo() { - this.uid = -1; - this.username = null; - } - - public long getUid() { - return uid; - } - - public String getUsername() { - return username; - } - } - - ProcessUserInfo build(int pid) { - ProcessUserInfo info = NON_EXISTENT_USER; - try { - Reader reader = source.getStatusReader(pid); - long uid = getUidFromProcfs(new BufferedReader(reader)); - String name = null; - try { - name = userNameUtil.getUserName(uid); - } catch (UserNameLookupException e) { - logger.log(Level.WARNING, "Unable to retrieve username for uid: " + uid, e); - } - info = new ProcessUserInfo(uid, name); - } catch (IOException e) { - logger.log(Level.WARNING, "Unable to read user info for " + pid, e); - } - - return info; - } - - /* - * Look for the following line: - * Uid: <RealUid> <EffectiveUid> <SavedUid> <FSUid> - */ - private long getUidFromProcfs(BufferedReader br) throws IOException { - long uid = -1; - String line; - while ((line = br.readLine()) != null) { - line = line.trim(); - if (line.startsWith(PROC_STATUS_UID)) { - String[] parts = line.split("\\s+"); - if (parts.length == 5) { - try { - // Use Real UID - uid = Long.parseLong(parts[1]); - } catch (NumberFormatException e) { - throw new IOException("Unexpected output from ps command", e); - } - } - else { - throw new IOException("Expected 5 parts from split /proc/${pid}/status output, got " + parts.length); - } - } - } - if (uid < 0) { - throw new IOException("Unable to determine UID from /proc/${pid}/status"); - } - return uid; - } - - -} -
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/username/internal/UserNameUtilImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.utils.username.internal; - -import java.io.IOException; - -import com.redhat.thermostat.agent.utils.username.UserNameLookupException; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; -import com.redhat.thermostat.shared.config.NativeLibraryResolver; - -public class UserNameUtilImpl implements UserNameUtil { - - static { - String lib = NativeLibraryResolver.getAbsoluteLibraryPath("UserNameUtilWrapper"); - System.load(lib); - } - - public String getUserName(long uid) throws UserNameLookupException { - String username = null; - if (uid >= 0) { - try { - // getUserName0 may throw IOException. We catch it here and - // throw a more specific exception in order to avoid API - // leakage. This exception is then dealt with in the caller of - // this method rather than here. This free's us from using the - // logger in a JNI class. - username = getUserName0(uid); - } catch (IOException e) { - throw new UserNameLookupException(e); - } - } - return username; - } - - private native String getUserName0(long uid) throws IOException; - -} -
--- a/agent/core/src/main/native/HostName.c Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright 2012-2014 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 - * <http://www.gnu.org/licenses/>. - * - * 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. - */ - -#include "com_redhat_thermostat_agent_utils_hostname_HostName.h" - -#include <jni.h> -#include <unistd.h> -#include <string.h> - -#if !defined(_WIN32) -# include <netdb.h> -#else // windows -# include <winsock2.h> -#endif - -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif /* NI_MAXHOST */ - -JNIEXPORT jstring JNICALL -Java_com_redhat_thermostat_agent_utils_hostname_HostName_getHostName - (JNIEnv *env, jclass HostNameClass) -{ - char hostname[NI_MAXHOST]; - memset(hostname, 0, sizeof(hostname)); - - if (gethostname(hostname, sizeof(hostname)) == 0) { - return (*env)->NewStringUTF(env, hostname); - } - return NULL; -} -
--- a/agent/core/src/main/native/UserNameUtilImpl.c Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright 2012-2014 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 - * <http://www.gnu.org/licenses/>. - * - * 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. - */ - -#include "com_redhat_thermostat_utils_username_internal_UserNameUtilImpl.h" - -#include <jni.h> -#include <string.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> - -#if !defined(_WIN32) -# include <pwd.h> -#else // windows -#endif - -static jint throw_IOException(JNIEnv *env, const char *message) { - const char *class_name = "java/io/IOException"; - jclass class = (*env)->FindClass(env, class_name); - if (class == NULL) { - return -1; - } - return (*env)->ThrowNew(env, class, message); -} - -#if !defined(_WIN32) - -JNIEXPORT jstring JNICALL -Java_com_redhat_thermostat_utils_username_internal_UserNameUtilImpl_getUserName0 - (JNIEnv *env, jclass ProcessUserInfoBuilderClass, jlong uid) { - size_t bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - if (bufsize < 0) { - throw_IOException(env, "Unable to retrieve recommended buffer size from sysconf"); - return NULL; - } - - char *buf = malloc(bufsize * sizeof(char)); - if (!buf) { - throw_IOException(env, "Unable to allocate buffer for username"); - return NULL; - } - - struct passwd pwd; - struct passwd *ret; - int rc = getpwuid_r(uid, &pwd, buf, bufsize, &ret); - if (rc) { - // Error occurred - const char *error_message = strerror(rc); - throw_IOException(env, error_message); - free(buf); - return NULL; - } - if (!ret) { - // No username found - char err_buf[128]; // Large enough for even the largest UIDs - snprintf(err_buf, sizeof(err_buf), "Username not found for uid: %ld", uid); - throw_IOException(env, err_buf); - free(buf); - return NULL; - } - - jstring name = (*env)->NewStringUTF(env, pwd.pw_name); - free(buf); - return name; -} - -#else // Windows -JNIEXPORT jstring JNICALL -Java_com_redhat_thermostat_utils_username_internal_UserNameUtilImpl_getUserName0 - (JNIEnv *env, jclass ProcessUserInfoBuilderClass, jlong uid) { - - // TODO - throw_IOException(env, "UserNameUtilImpl.getUserName() no yet implemented on Windows"); - jstring name = (*env)->NewStringUTF(env, "xxxuserxxx"); - return name; -} -#endif - -
--- a/agent/core/src/main/native/WindowsHelperImpl.c Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,350 +0,0 @@ -/* - * Copyright 2012-2016 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 - * <http://www.gnu.org/licenses/>. - * - * 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. - */ - -#include "com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl.h" -#include <jni.h> -#include <unistd.h> -#include <string.h> - -#if !defined(_WIN32) -# include <netdb.h> -#else // windows -# include <winsock2.h> -# include <psapi.h> -#endif - -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif /* NI_MAXHOST */ - -#if defined(NDEBUG) -static void testLength(JNIEnv* env, jlongArray array, minLength) {} -#else -static void testLength(JNIEnv* env, jlongArray array, minLength) { - // sanity test - jsize len = (*env)->GetArrayLength(env, array); - assert(len >= minLength); -} -#endif - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getHostName0 - * Signature: ()Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getHostName0 - (JNIEnv *env, jclass winHelperClass, jboolean prependDomain) -{ - char hostname[NI_MAXHOST]; - memset(hostname, 0, sizeof(hostname)); - - if (gethostname(hostname, sizeof(hostname)) == 0) { - return (*env)->NewStringUTF(env, hostname); - } - return NULL; -} - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getOSVersion0 - * Signature: ([J)V - */ -JNIEXPORT void JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getOSVersion0 - (JNIEnv *env, jclass winHelperClass, jlongArray array) -{ - testLength(env, array, 3); - - // Get the element pointer - jlong* data = (*env)->GetLongArrayElements(env, array, 0); - - OSVERSIONINFOEX vinfo; - vinfo.dwOSVersionInfoSize = sizeof(vinfo); - GetVersionEx(&vinfo); - data[0] = vinfo.dwMajorVersion; - data[1] = vinfo.dwMinorVersion; - data[2] = vinfo.dwBuildNumber; - - (*env)->ReleaseLongArrayElements(env, array, data, 0); -} - - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getUid0 - * Signature: (I)I - */ -JNIEXPORT jint JNICALL -Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getUid0 - (JNIEnv *env, jclass winHelperClass, jint pid) -{ - // TODO - implement this stub - return 987654321; -} - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getUserName0 - * Signature: (I)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getUserName0 - (JNIEnv *env, jclass winHelperClass, jint pid, jboolean prependDomain) -{ - // TODO - implement this stub - return (*env)->NewStringUTF(env, "(unavailable)"); -} - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getEnvironment0 - * Signature: ()[Ljava/lang/String; - */ -JNIEXPORT jobjectArray JNICALL -Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getEnvironment0 - (JNIEnv *env, jclass winHelperClass, jint pid) -{ - // TODO - implement this stub - jobjectArray ret = (jobjectArray)(*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, "")); - return ret; -} - - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getGlobalMemoryStatus0 - * Signature: ([J)V - */ -JNIEXPORT boolean JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getGlobalMemoryStatus0 - (JNIEnv *env, jclass winHelperClass, jlongArray array) -{ - testLength(env, array, 8); - - // Get the element pointer - jlong* data = (*env)->GetLongArrayElements(env, array, 0); - - // get the memory info - MEMORYSTATUSEX statex; - statex.dwLength = sizeof(statex); - GlobalMemoryStatusEx(&statex); - data[0] = statex.dwMemoryLoad; - data[1] = statex.ullTotalPhys; - data[2] = statex.ullAvailPhys; - data[3] = statex.ullTotalPageFile; - data[4] = statex.ullAvailPageFile; - data[5] = statex.ullTotalVirtual; - data[6] = statex.ullAvailVirtual; - data[7] = statex.ullAvailExtendedVirtual; - - (*env)->ReleaseLongArrayElements(env, array, data, 0); - return TRUE; -} - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getPerformanceInfo0 - * Signature: ([J)V - */ -JNIEXPORT boolean JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getPerformanceInfo0 - (JNIEnv *env, jclass winHelperClass, jlongArray array) -{ - testLength(env, array, 13); - - // Get the element pointer - jlong* data = (*env)->GetLongArrayElements(env, array, 0); - - /** - // from PERFORMANCE_INFORMATION (13 values) - SIZE_T CommitTotal; - SIZE_T CommitLimit; - SIZE_T CommitPeak; - SIZE_T PhysicalTotal; - SIZE_T PhysicalAvailable; - SIZE_T SystemCache; - SIZE_T KernelTotal; - SIZE_T KernelPaged; - SIZE_T KernelNonpaged; - SIZE_T PageSize; - DWORD HandleCount; - DWORD ProcessCount; - DWORD ThreadCount; - */ - - // get the memeory info - PERFORMANCE_INFORMATION statex; - statex.cb = sizeof(statex); - GetPerformanceInfo(&statex, statex.cb); - data[0] = statex.CommitTotal; - data[1] = statex.CommitLimit; - data[2] = statex.CommitPeak; - data[3] = statex.PhysicalTotal; - data[4] = statex.PhysicalAvailable; - data[5] = statex.SystemCache; - data[6] = statex.KernelTotal; - data[7] = statex.KernelPaged; - data[8] = statex.KernelNonpaged; - data[9] = statex.PageSize; - data[10] = statex.HandleCount; - data[11] = statex.ProcessCount; - data[12] = statex.ThreadCount; - - (*env)->ReleaseLongArrayElements(env, array, data, 0); - return TRUE; -} - -static unsigned __int64 convertFileTimeToInt64( const FILETIME * pFileTime ) -{ - ULARGE_INTEGER largeInt; - - largeInt.LowPart = pFileTime->dwLowDateTime; - largeInt.HighPart = pFileTime->dwHighDateTime; - - return largeInt.QuadPart; -} - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getProcessMemoryInfo0 - * Signature: (I[J)V - */ -JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getProcessInfo0 - (JNIEnv *env, jclass winHelperClass, jint pid, jlongArray array) -{ - testLength(env, array, 4); - - // Get the element pointer - jlong* data = (*env)->GetLongArrayElements(env, array, 0); - - HANDLE hProcess; - PROCESS_MEMORY_COUNTERS pmc; - - hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid ); - if (NULL == hProcess) - return FALSE; - - pmc.cb = sizeof(pmc); - if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) { - data[0] = pmc.WorkingSetSize; - } - else { - (*env)->ReleaseLongArrayElements(env, array, data, 0); - return FALSE; - } - - FILETIME creationTime; - FILETIME exitTime; - FILETIME kernelTime; - FILETIME userTime; - - if ( GetProcessTimes( hProcess, &creationTime, &exitTime, &kernelTime, &userTime ) ) { - data[1] = convertFileTimeToInt64(&userTime); - data[2] = convertFileTimeToInt64(&kernelTime); - } - - CloseHandle(hProcess); - - (*env)->ReleaseLongArrayElements(env, array, data, 0); - return TRUE; -} - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getCPUString0 - * Signature: ()Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getCPUString0 - (JNIEnv *env, jclass winHelperClass) -{ - // Get extended ids. - int CPUInfo[4] = {-1}; - __cpuid(CPUInfo, 0x80000000); - unsigned int nExIds = CPUInfo[0]; - - // Get the information associated with each extended ID. - char CPUBrandString[0x40] = { 0 }; - for( unsigned int i=0x80000000; i<=nExIds; ++i) - { - __cpuid(CPUInfo, i); - - // Interpret CPU brand string and cache information. - if (i == 0x80000002) - { - memcpy( CPUBrandString, - CPUInfo, - sizeof(CPUInfo)); - } - else if( i == 0x80000003 ) - { - memcpy( CPUBrandString + 16, - CPUInfo, - sizeof(CPUInfo)); - } - else if( i == 0x80000004 ) - { - memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo)); - } - } - return (*env)->NewStringUTF(env, CPUBrandString); - -} - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getCPUCount0 - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getCPUCount0 - (JNIEnv *env, jclass winHelperClass) -{ - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - - return sysinfo.dwNumberOfProcessors; -} - -/* - * Class: com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl - * Method: getClockTicksPerSecond0 - * Signature: ()I - */ -JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getClockTicksPerSecond0 - (JNIEnv *env, jclass winHelperClass) -{ - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - - return (jlong)(freq.QuadPart); -}
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -44,6 +44,7 @@ import java.io.File; +import com.redhat.thermostat.common.portability.UserNameUtil; import org.junit.Before; import org.junit.Test; import org.osgi.framework.ServiceRegistration; @@ -51,13 +52,11 @@ import com.redhat.thermostat.agent.VmBlacklist; import com.redhat.thermostat.agent.ipc.server.AgentIPCService; import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.NativeLibraryResolver; import com.redhat.thermostat.testutils.StubBundleContext; import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolControl; import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl; -import com.redhat.thermostat.utils.username.internal.UserNameUtilImpl; public class ActivatorTest { @@ -73,6 +72,11 @@ context = new StubBundleContext(); context.registerService(CommonPaths.class.getName(), paths, null); + + // required by MXBeanConnectionPoolImpl + UserNameUtil userNameUtil = mock(UserNameUtil.class); + context.registerService(UserNameUtil.class.getName(), userNameUtil, null); + AgentIPCService ipcService = mock(AgentIPCService.class); ipcReg = context.registerService(AgentIPCService.class.getName(), ipcService, null); } @@ -84,7 +88,6 @@ assertTrue(context.isServiceRegistered(MXBeanConnectionPool.class.getName(), MXBeanConnectionPoolImpl.class)); assertTrue(context.isServiceRegistered(MXBeanConnectionPoolControl.class.getName(), MXBeanConnectionPoolImpl.class)); - assertTrue(context.isServiceRegistered(UserNameUtil.class.getName(), UserNameUtilImpl.class)); assertTrue(context.isServiceRegistered(VmBlacklist.class.getName(), VmBlacklistImpl.class)); }
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/utils/ProcessCheckerTest.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.io.File; - -import org.junit.Test; - -public class ProcessCheckerTest { - - private static final int SOME_PID = 80980; - - @Test - public void testProcessExists() { - basicTest(true); - } - - @Test - public void testProcessNotExisting() { - basicTest(false); - } - - private void basicTest(boolean expected) { - final File baseFile = mock(File.class); - when(baseFile.exists()).thenReturn(expected); - ProcessChecker process = new ProcessChecker() { - @Override - File mapToFile(int pid) { - assertEquals(SOME_PID, pid); - return baseFile; - } - }; - assertEquals(expected, process.exists(SOME_PID)); - } -}
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/utils/SysConfTest.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -public class SysConfTest { - - @Test - public void test() { - long ticksPerSecond = SysConf.getClockTicksPerSecond(); - assertTrue(ticksPerSecond >= 1); - } -} -
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/utils/linux/ProcDataSourceTest.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils.linux; - -import static org.junit.Assert.*; - -import java.io.IOException; -import java.io.Reader; - -import com.redhat.thermostat.shared.config.OS; -import org.junit.Assume; -import org.junit.Test; - -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.testutils.TestUtils; - -public class ProcDataSourceTest { - - @Test - public void testGetCpuInfoReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); - Reader r = new ProcDataSource().getCpuInfoReader(); - assertNotNull(r); - } - - @Test - public void testGetCpuLoadReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); - Reader r = new ProcDataSource().getCpuLoadReader(); - assertNotNull(r); - } - - @Test - public void testGetMemInfoReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); - Reader r = new ProcDataSource().getMemInfoReader(); - assertNotNull(r); - } - - @Test - public void testGetStatReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); - int pid = TestUtils.getProcessId(); - Reader r = new ProcDataSource().getStatReader(pid); - assertNotNull(r); - } - - @Test - public void testGetEnvironReader() throws IOException { - Assume.assumeTrue(OS.IS_UNIX); - int pid = TestUtils.getProcessId(); - Reader r = new ProcDataSource().getEnvironReader(pid); - assertNotNull(r); - } - - @Test - public void testIoReader() throws Exception { - Assume.assumeTrue(OS.IS_UNIX); - int pid = TestUtils.getProcessId(); - Reader r = new ProcDataSource().getIoReader(pid); - assertNotNull(r); - } - - @Test - public void testStatReader() throws Exception { - Assume.assumeTrue(OS.IS_UNIX); - int pid = TestUtils.getProcessId(); - Reader r = new ProcDataSource().getStatReader(pid); - assertNotNull(r); - } - - @Test - public void testStatusReader() throws Exception { - Assume.assumeTrue(OS.IS_UNIX); - int pid = TestUtils.getProcessId(); - Reader r = new ProcDataSource().getStatusReader(pid); - assertNotNull(r); - } -} -
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/utils/windows/WindowsHelperImplTest.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.agent.utils.windows; - -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; -import com.redhat.thermostat.shared.config.OS; - -import org.junit.Assume; -import org.junit.Ignore; -import org.junit.Test; - -import java.util.Map; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * These tests are disabled until we get the DLL path issues sorted out - * TODO - These tests currently fail on Windows because the helper DLL isn't on the execution path - */ - -@Ignore -public class WindowsHelperImplTest { - - @Test - public void loadNativeLib() { - Assume.assumeTrue(OS.IS_WINDOWS); - final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE; - assertNotNull(impl); - } - - @Test - public void testGetHostInfo() { - Assume.assumeTrue(OS.IS_WINDOWS); - final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE; - assertNotNull(impl); - assertContainsData(impl.getHostName()); - assertContainsData(impl.getOSName()); - assertTrue(impl.getOSName().toLowerCase().contains("win")); - assertContainsData(impl.getOSVersion()); - assertContainsData(impl.getCPUModel()); - assertTrue(impl.getCPUCount() > 0); - assertTrue(impl.getTotalMemory() > 0); - } - - @Test - @Ignore - public void testGetProcessInfo() { - Assume.assumeTrue(OS.IS_WINDOWS); - final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE; - assertNotNull(impl); - int pid = /*TODO: retrieve current process identifier*/0; - assertContainsData(impl.getUserName(pid)); - assertTrue(impl.getUid(pid) >= 0); - Map<String,String> envMap = impl.getEnvironment(pid); - assertNotNull(envMap); - assertFalse(envMap.isEmpty()); - } - - private static void assertContainsData( final String s ) { - assertNotNull(s); - assertFalse(s.isEmpty()); - } -}
--- a/agent/core/src/test/java/com/redhat/thermostat/backend/internal/VmMonitorTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/core/src/test/java/com/redhat/thermostat/backend/internal/VmMonitorTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -58,7 +58,7 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import com.redhat.thermostat.agent.utils.ProcessChecker; +import com.redhat.thermostat.common.portability.ProcessChecker; import com.redhat.thermostat.backend.VmUpdateListener; import sun.jvmstat.monitor.HostIdentifier;
--- a/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -53,6 +53,8 @@ import java.nio.file.attribute.UserPrincipal; import java.nio.file.attribute.UserPrincipalLookupService; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; import org.junit.Before; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; @@ -67,7 +69,6 @@ import com.redhat.thermostat.agent.utils.management.MXBeanConnectionException; import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl.ConnectorCreator; import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl.FileSystemUtils; -import com.redhat.thermostat.utils.management.internal.ProcessUserInfoBuilder.ProcessUserInfo; public class MXBeanConnectionPoolImplTest {
--- a/agent/ipc/server/pom.xml Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/ipc/server/pom.xml Mon Jan 23 10:11:31 2017 -0500 @@ -91,6 +91,11 @@ <version>${project.version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-portability</artifactId> + <version>1.99.12-SNAPSHOT</version> + </dependency> </dependencies> <build>
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/IPCConfigurationWriter.java Fri Jan 20 10:48:09 2017 -0500 +++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/IPCConfigurationWriter.java Mon Jan 23 10:11:31 2017 -0500 @@ -43,14 +43,13 @@ import java.util.Properties; import com.redhat.thermostat.agent.ipc.common.internal.IPCType; +import com.redhat.thermostat.common.portability.PortableProcessImpl; import com.redhat.thermostat.shared.config.OS; class IPCConfigurationWriter { static final String PROP_IPC_TYPE = "type"; private static final String PROP_UNIX_SOCKET_DIR = "unixsocket.dir"; - - private static final String PROP_TCP_SOCKET_SUFFIX= ".tcpsocket.port"; //private static final String TCP_SOCKET_JUMBO_FRAMES = "tcpsocket.jumboframes"; @@ -96,17 +95,25 @@ props.setProperty(PROP_IPC_TYPE, OS.IS_UNIX ? IPCType.UNIX_SOCKET.getConfigValue() : IPCType.TCP_SOCKET.getConfigValue()); // unix socket will work without configuration (creates sockets in tmp directory - // but tcpsocket always needs ports (in the future, should support service discovery) + // but tcpsocket always needs ports predefined (in the future, should support service discovery) // this implementation is flawed; // the unused ports might be in used by a process that simply wasn't running at thermostat setup time. { - int cmdPort = findUnusedTCPSocket(TEST_SOCKET_LOW,TEST_SOCKET_HIGH); - int aport = cmdPort == 0 ? 0 : findUnusedTCPSocket(cmdPort+1,TEST_SOCKET_HIGH); + int cmdPort = findUnusedTCPSocket(TEST_SOCKET_LOW, TEST_SOCKET_HIGH); + int aport = cmdPort == 0 ? 0 : findUnusedTCPSocket(cmdPort + 1, TEST_SOCKET_HIGH); props.setProperty("command-channel" + PROP_TCP_SOCKET_SUFFIX, Integer.toString(cmdPort)); props.setProperty("agent-proxy" + PROP_TCP_SOCKET_SUFFIX, Integer.toString(aport)); + + // write a property for each user on the system - currently only the current user + // note: this is required for UNIX too + if (OS.IS_WINDOWS) { + int uport = aport == 0 ? 0 : findUnusedTCPSocket( aport + 1, TEST_SOCKET_HIGH); + int uid = PortableProcessImpl.INSTANCE.getUid(0); // if pid=0, gets uid of current process + props.setProperty("agent-proxy-" + uid + PROP_TCP_SOCKET_SUFFIX, Integer.toString(uport)); + } } try (FileOutputStream fos = helper.createStream(configFile)) {
--- a/common/pom.xml Fri Jan 20 10:48:09 2017 -0500 +++ b/common/pom.xml Mon Jan 23 10:11:31 2017 -0500 @@ -67,6 +67,7 @@ <modules> <module>core</module> <module>command</module> + <module>portability</module> <module>test</module> </modules>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/Makefile Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,86 @@ +CC = gcc +JAVAH = javah +MYCFLAGS = -c -Wall $(EXTRA_CFLAGS) +MYLDFLAGS = -shared $(EXTRA_CFLAGS) +COPY = cp -a + +CLASSPATH = target/classes/ +TARGET_DIR = target + +ifeq ($(OS),Windows_NT) + JNI_PLATFORM = win32 + SO_PREFIX = + SO_SUFFIX = .dll +else + JNI_PLATFORM = linux + SO_PREFIX = lib + SO_SUFFIX = .so + MYCFLAGS += -fPIC + MYLDFLAGS += -fPIC +endif + +INCLUDE = -I $(TARGET_DIR) -I "$(JAVA_HOME)/include/" -I "$(JAVA_HOME)/include/$(JNI_PLATFORM)" + +HOSTNAME_SOURCES = src/main/native/HostName.c +HOSTNAME_TARGET = $(TARGET_DIR)/HostName.c +HOSTNAME_OBJECTS = $(HOSTNAME_TARGET:.c=.o) +HOSTNAME_EXECUTABLE = $(SO_PREFIX)HostNameWrapper$(SO_SUFFIX) + +USERNAME_SOURCES = src/main/native/UserNameUtilImpl.c +USERNAME_TARGET = $(TARGET_DIR)/UserNameUtilImpl.c +USERNAME_OBJECTS = $(USERNAME_TARGET:.c=.o) +USERNAME_EXECUTABLE = $(SO_PREFIX)UserNameUtilWrapper$(SO_SUFFIX) + +WINHELPER_SOURCES = src/main/native/WindowsHelperImpl.c +WINHELPER_TARGET = $(TARGET_DIR)/WindowsHelperImpl.c +WINHELPER_OBJECTS = $(WINHELPER_TARGET:.c=.o) +WINHELPER_EXECUTABLE = $(SO_PREFIX)WindowsHelperWrapper$(SO_SUFFIX) + +EXECUTABLES = $(HOSTNAME_EXECUTABLE) $(USERNAME_EXECUTABLE) + +.PHONY:UserNameUtilImpl +JNI_LIST = com.redhat.thermostat.common.portability.HostName com.redhat.thermostat.common.portability.internal.linux.UserNameUtilImpl + +ifeq ($(OS),Windows_NT) + EXECUTABLES += $(WINHELPER_EXECUTABLE) + JNI_LIST += com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl +endif + +$(JNI_LIST): + $(JAVAH) -force -classpath $(CLASSPATH) -d $(TARGET_DIR) $(JNI_LIST) + +all: $(JNI_LIST) init $(HOSTNAME_SOURCES) $(USERNAME_SOURCES) $(WINHELPER_SOURCES) $(EXECUTABLES) + +.PHONY: +init: + $(COPY) $(HOSTNAME_SOURCES) $(HOSTNAME_TARGET) + $(COPY) $(USERNAME_SOURCES) $(USERNAME_TARGET) + $(COPY) $(WINHELPER_SOURCES) $(WINHELPER_TARGET) + +$(HOSTNAME_EXECUTABLE): $(HOSTNAME_OBJECTS) + $(CC) $(MYLDFLAGS) $(LDFLAGS) $(HOSTNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@ + +$(USERNAME_EXECUTABLE): $(USERNAME_OBJECTS) + $(CC) $(MYLDFLAGS) $(LDFLAGS) $(USERNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@ + +$(WINHELPER_EXECUTABLE): $(WINHELPER_OBJECTS) + $(CC) $(MYLDFLAGS) $(LDFLAGS) $(WINHELPER_OBJECTS) $(PLATFORM_LIBS) -l psapi -o $(TARGET_DIR)/$@ + +.c.o: + $(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@ + +.cpp.o: + $(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@ + +clean-lib: + rm -f $(TARGET_DIR)/$(HOSTNAME_EXECUTABLE) + rm -f $(TARGET_DIR)/$(USERNAME_EXECUTABLE) + rm -f $(TARGET_DIR)/$(WINHELPER_EXECUTABLE) + +clean-obj: + rm -f $(HOSTNAME_OBJECTS) $(HOSTNAME_TARGET) + rm -f $(USERNAME_OBJECTS) $(USERNAME_TARGET) + rm -f $(WINHELPER_OBJECTS) $(WINHELPER_TARGET) + +clean: clean-obj clean-lib +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/pom.xml Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,223 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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 + <http://www.gnu.org/licenses/>. + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common</artifactId> + <version>1.99.12-SNAPSHOT</version> + </parent> + + <artifactId>thermostat-common-portability</artifactId> + <packaging>bundle</packaging> + + <name>Thermostat Common Portability Code</name> + + <profiles> + <profile> + <id>default</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + </profile> + + <profile> + <id>linux</id> + <activation> + <os><family>Unix</family></os> + </activation> + <properties> + <platform.libs/> + </properties> + </profile> + + <profile> + <id>windows</id> + <activation> + <os><family>Windows</family></os> + </activation> + <properties> + <platform.libs>-lws2_32</platform.libs> + <sharedlib.prefix/> + <sharedlib.suffix>.dll</sharedlib.suffix> + </properties> + </profile> + </profiles> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-annotations</artifactId> + <version>${project.version}</version> + <!--scope>test</scope--> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-test</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-shared-config</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + </dependency> + </dependencies> + + <build> + + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> + <Bundle-SymbolicName>com.redhat.thermostat.common.portability</Bundle-SymbolicName> + <Bundle-Activator>com.redhat.thermostat.common.portability.internal.Activator</Bundle-Activator> + <Export-Package> + com.redhat.thermostat.common.portability, + com.redhat.thermostat.common.portability.linux + </Export-Package> + <Private-Package> + com.redhat.thermostat.common.portability.internal, + com.redhat.thermostat.common.portability.internal.linux, + com.redhat.thermostat.common.portability.internal.windows + </Private-Package> + <!-- Do not autogenerate uses clauses in Manifests --> + <_nouses>true</_nouses> + </instructions> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <systemPropertyVariables> + <com.redhat.thermostat.shared.loader.testNativesHome>${project.build.directory}</com.redhat.thermostat.shared.loader.testNativesHome> + </systemPropertyVariables> + </configuration> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <phase>compile</phase> + <goals> + <goal>exec</goal> + </goals> + </execution> + </executions> + <configuration> + <executable>make</executable> + <arguments> + <argument>all</argument> + <argument>CC=${c.compiler}</argument> + <argument>SO_PREFIX=${sharedlib.prefix}</argument> + <argument>SO_SUFFIX=${sharedlib.suffix}</argument> + <argument>EXTRA_CFLAGS=${cflags}</argument> + <argument>JNI_PLATFORM=${jni.platform}</argument> + <argument>PLATFORM_LIBS=${platform.libs}</argument> + </arguments> + <systemProperties> + <systemProperty> + <key>JAVA_HOME</key> + <value>${java.home}</value> + </systemProperty> + </systemProperties> + </configuration> + </plugin> + </plugins> + + <pluginManagement> + <plugins> + <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.--> + <plugin> + <groupId>org.eclipse.m2e</groupId> + <artifactId>lifecycle-mapping</artifactId> + <configuration> + <lifecycleMappingMetadata> + <pluginExecutions> + <pluginExecution> + <pluginExecutionFilter> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <versionRange>[1.2.1,)</versionRange> + <goals> + <goal>exec</goal> + </goals> + </pluginExecutionFilter> + <action> + <ignore/> + </action> + </pluginExecution> + </pluginExecutions> + </lifecycleMappingMetadata> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + +</project> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/HostName.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,57 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import com.redhat.thermostat.shared.config.NativeLibraryResolver; + +/** + * Finds the current host name without doing a DNS lookup + */ +public class HostName { + + static { + String lib = NativeLibraryResolver.getAbsoluteLibraryPath("HostNameWrapper"); + System.load(lib); + } + + public static String getLocalHostName() { + return getHostName(); + } + + private static native String getHostName(); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHost.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,56 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +public interface PortableHost { + + String getHostName(); + + String getOSName(); + + String getOSVersion(); + + String getCPUModel(); + + int getCPUCount(); + + long getTotalMemory(); + + long getClockTicksPerSecond(); + + PortableMemoryStat getMemoryStat(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHostImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,46 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import com.redhat.thermostat.common.portability.internal.windows.WindowsHostImpl; +import com.redhat.thermostat.shared.config.OS; + +public class PortableHostImpl { + + public static final PortableHost INSTANCE = OS.IS_WINDOWS ? WindowsHostImpl.INSTANCE : null; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableMemoryStat.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,89 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +public class PortableMemoryStat { + + private final long timeStamp; + private final long total; + private final long free; + private final long buffers; + private final long cached; + private final long swapTotal; + private final long swapFree; + private final long commitLimit; + + public PortableMemoryStat(long timeStamp, long total, long free, long buffers, long cached, long swapTotal, long swapFree, long commitLimit) { + this.timeStamp = timeStamp; + this.total = total; + this.free = free; + this.buffers = buffers; + this.cached = cached; + this.swapTotal = swapTotal; + this.swapFree = swapFree; + this.commitLimit = commitLimit; + } + + public long getTimeStamp() { + return timeStamp; + } + public long getTotal() { + return total; + } + public long getFree() { + return free; + } + public long getBuffers() { + return buffers; + } + public long getCached() { + return cached; + } + public long getSwapTotal() { + return swapTotal; + } + public long getSwapFree() { + return swapFree; + } + public long getCommitLimit() { + return commitLimit; + } + + public static PortableMemoryStat build() { + return PortableHostImpl.INSTANCE.getMemoryStat(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,62 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import com.redhat.thermostat.common.Clock; + +import java.util.Map; + +public interface PortableProcess { + + boolean exists(int pid); + + String getUserName(int pid); + + int getUid(int pid); + + Map<String, String> getEnvironment(int pid); + + PortableProcessStat getProcessStat(int pid); + + PortableVmIoStat getVmIoStat(Clock clock, int pid); + + boolean terminateProcess(int pid); + + boolean terminateProcess(int pid, boolean wait); + + boolean terminateProcess(int pid, int exitcode, int waitMillis); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,46 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import com.redhat.thermostat.common.portability.internal.linux.LinuxProcessImpl; +import com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl; +import com.redhat.thermostat.common.portability.internal.windows.WindowsProcessImpl; +import com.redhat.thermostat.shared.config.OS; + +public final class PortableProcessImpl { + public static final PortableProcess INSTANCE = OS.IS_WINDOWS ? WindowsProcessImpl.INSTANCE : LinuxProcessImpl.INSTANCE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessStat.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,77 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +public class PortableProcessStat { + + /* All times are measured in clock ticks */ + + private final int pid; + private final long userTime; + private final long kernelTime; + + public PortableProcessStat(int pid, long userTime, long kernelTime) { + this.pid = pid; + this.userTime = userTime; + this.kernelTime = kernelTime; + } + + public int getPid() { + return pid; + } + + /** + * @return the time this process has spent in user-mode as a number of + * kernel ticks + */ + public long getUserTime() { + return userTime; + } + + /** + * @return the time this process spent in kernel-mode as a number of kernel + * ticks + */ + public long getKernelTime() { + return kernelTime; + } + + public static PortableProcessStat build(int pid) { + return PortableProcessImpl.INSTANCE.getProcessStat(pid); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableVmIoStat.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,81 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import com.redhat.thermostat.common.Clock; + +public class PortableVmIoStat { + + private final long timeStamp; + + private final long readSyscalls; + private final long writeSyscalls; + private final long charactersRead; + private final long charactersWritten; + + public PortableVmIoStat(final long timeStamp, final long readSyscalls, final long writeSyscalls, final long charactersRead, final long charactersWritten) { + this.timeStamp = timeStamp; + this.readSyscalls = readSyscalls; + this.writeSyscalls = writeSyscalls; + this.charactersRead = charactersRead; + this.charactersWritten = charactersWritten; + } + + public static PortableVmIoStat build(Clock clock, int pid) { + return PortableProcessImpl.INSTANCE.getVmIoStat(clock, pid); + } + + public long getTimeStamp() { + return timeStamp; + } + + public long getReadSyscalls() { + return readSyscalls; + } + + public long getWriteSyscalls() { + return writeSyscalls; + } + + public long getCharactersRead() { + return charactersRead; + } + + public long getCharactersWritten() { + return charactersWritten; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessChecker.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,71 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl; +import com.redhat.thermostat.shared.config.OS; + +import java.io.File; +/** + * Utility for checking whether a process exists or not. + * + * Implementation note: This is Linux specific. + * + */ +public class ProcessChecker { + + private static final boolean is_linux = OS.IS_LINUX; + + public boolean exists(int pid) { + return is_linux ? existsLinux(pid) : existsWindows(pid); + } + + private boolean existsLinux(int pid) { + File procFile = mapToFile(pid); + return procFile.exists(); + } + + private boolean existsWindows(int pid) { + return WindowsHelperImpl.INSTANCE.exists(pid); + } + + // testing-hook + File mapToFile(int pid) { + return new File("/proc/" + pid); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessUserInfo.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,74 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import com.redhat.thermostat.common.portability.internal.linux.LinuxProcessUserInfoBuilderImpl; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.internal.windows.WindowsUserInfoBuilderImpl; +import com.redhat.thermostat.shared.config.OS; + +public class ProcessUserInfo { + + private long uid; + private String username; + + public ProcessUserInfo(long uid, String username) { + this.uid = uid; + this.username = username; + } + + public ProcessUserInfo() { + this.uid = -1; + this.username = null; + } + + public long getUid() { + return uid; + } + + public String getUsername() { + return username; + } + + public static ProcessUserInfoBuilder createBuilder(ProcDataSource source, UserNameUtil userNameUtil) { + return OS.IS_LINUX ? new LinuxProcessUserInfoBuilderImpl(source, userNameUtil) : new WindowsUserInfoBuilderImpl(); + } + + public static ProcessUserInfoBuilder createBuilder() { + return OS.IS_LINUX ? new LinuxProcessUserInfoBuilderImpl() : new WindowsUserInfoBuilderImpl(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessUserInfoBuilder.java Mon Jan 23 10:11:31 2017 -0500 @@ -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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +/** + * Interface for ProcessUserInfo builders + */ +public interface ProcessUserInfoBuilder { + ProcessUserInfo build(int pid); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/SysConf.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,88 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import com.redhat.thermostat.shared.config.OS; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * A wrapper over POSIX's sysconf. + * <p> + * Implementation notes: uses {@code getconf(1)} + */ +public class SysConf { + + private SysConf() { + /* do not initialize */ + } + + public static long getClockTicksPerSecond() { + return OS.IS_LINUX ? getLinuxClockTicksPerSecond() : getWindowsClockTicksPerSecond(); + } + + private static long getWindowsClockTicksPerSecond() { + return PortableHostImpl.INSTANCE.getClockTicksPerSecond(); + } + + public static long getLinuxClockTicksPerSecond() { + String ticks = sysConf("CLK_TCK"); + try { + return Long.valueOf(ticks); + } catch (NumberFormatException nfe) { + return 0; + } + } + + private static String sysConf(String arg) { + try { + Process process = Runtime.getRuntime().exec(new String[] { "getconf", arg }); + int result = process.waitFor(); + if (result != 0) { + return null; + } + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + return reader.readLine(); + } + } catch (IOException | InterruptedException e) { + return null; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/UserNameLookupException.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,52 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +/** + * + * Thrown on user name lookup error. + * + * @see UserNameUtil + */ +@SuppressWarnings("serial") +public class UserNameLookupException extends Exception { + + public UserNameLookupException(Throwable cause) { + super(cause); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/UserNameUtil.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,59 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import com.redhat.thermostat.annotations.Service; + +/** + * Utility to query the operating system for a user name. + */ +@Service +public interface UserNameUtil { + + /** + * Gets the user name corresponding to the provided UID. + * + * @param uid + * The UID whose name to return. + * @throws UserNameLookupException + * If an error occurred during retrieval of the user name. + * @return The user name if found. null if no such UID exists. + */ + String getUserName(long uid) throws UserNameLookupException; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/Activator.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,59 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal; + +import com.redhat.thermostat.common.portability.UserNameUtil; +import com.redhat.thermostat.common.portability.internal.linux.UserNameUtilImpl; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + + @Override + public void start(final BundleContext context) throws Exception { + + // No deps, register immediately + UserNameUtilImpl usernameUtil = new UserNameUtilImpl(); + context.registerService(UserNameUtil.class, usernameUtil, null); + } + + @Override + public void stop(BundleContext context) throws Exception { + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/UnimplementedError.java Mon Jan 23 10:11:31 2017 -0500 @@ -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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal; + +public class UnimplementedError extends Error { + + private final String msg; + + public UnimplementedError(String msg ) { + this.msg = msg; + } + + public String toString() { + return "Unimplemented: " + msg; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,100 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.linux; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.portability.*; +import com.redhat.thermostat.common.portability.internal.UnimplementedError; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; + +import java.util.Map; + +public class LinuxProcessImpl implements PortableProcess { + + private final ProcDataSource dataSource; + + public static LinuxProcessImpl INSTANCE = new LinuxProcessImpl(new ProcDataSource()); + + LinuxProcessImpl(ProcDataSource ds) { + this.dataSource = ds; + } + + @Override + public boolean exists(int pid) { + return new ProcessChecker().exists(pid); + } + + @Override + public String getUserName(int pid) { + throw new UnimplementedError("getUserName()"); + } + + @Override + public int getUid(int pid) { + throw new UnimplementedError("getUid()"); + } + + @Override + public Map<String, String> getEnvironment(int pid) { + throw new UnimplementedError("getEnvironment()"); + } + + @Override + public PortableProcessStat getProcessStat(int pid) { + throw new UnimplementedError("PortableProcessStat()"); + } + + @Override + public PortableVmIoStat getVmIoStat(Clock clock, int pid) { + throw new UnimplementedError("getVmIoStat()"); + } + + @Override + public boolean terminateProcess(int pid) { + throw new UnimplementedError("terminateProcess()"); + } + + @Override + public boolean terminateProcess(int pid, boolean wait) { + throw new UnimplementedError("terminateProcess()"); + } + + @Override + public boolean terminateProcess(int pid, int exitcode, int waitMillis) { + throw new UnimplementedError("terminateProcess()"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessUserInfoBuilderImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,118 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.linux; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.portability.UserNameUtil; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; +import com.redhat.thermostat.common.portability.UserNameLookupException; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.utils.LoggingUtils; + +public class LinuxProcessUserInfoBuilderImpl implements ProcessUserInfoBuilder { + + private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo(); + private static final String PROC_STATUS_UID = "Uid:"; + private static final Logger logger = LoggingUtils.getLogger(LinuxProcessUserInfoBuilderImpl.class); + private ProcDataSource source; + private UserNameUtil userNameUtil; + + public LinuxProcessUserInfoBuilderImpl() { + this(new ProcDataSource(), new UserNameUtilImpl()); + } + + public LinuxProcessUserInfoBuilderImpl(ProcDataSource source, UserNameUtil userNameUtil) { + this.source = source; + this.userNameUtil = userNameUtil; + } + + public ProcessUserInfo build(int pid) { + ProcessUserInfo info = NON_EXISTENT_USER; + try { + Reader reader = source.getStatusReader(pid); + long uid = getUidFromProcfs(new BufferedReader(reader)); + String name = null; + try { + name = userNameUtil.getUserName(uid); + } catch (UserNameLookupException e) { + logger.log(Level.WARNING, "Unable to retrieve username for uid: " + uid, e); + } + info = new ProcessUserInfo(uid, name); + } catch (IOException e) { + logger.log(Level.WARNING, "Unable to read user info for " + pid, e); + } + + return info; + } + + /* + * Look for the following line: + * Uid: <RealUid> <EffectiveUid> <SavedUid> <FSUid> + */ + private long getUidFromProcfs(BufferedReader br) throws IOException { + long uid = -1; + String line; + while ((line = br.readLine()) != null) { + line = line.trim(); + if (line.startsWith(PROC_STATUS_UID)) { + String[] parts = line.split("\\s+"); + if (parts.length == 5) { + try { + // Use Real UID + uid = Long.parseLong(parts[1]); + } catch (NumberFormatException e) { + throw new IOException("Unexpected output from ps command", e); + } + } + else { + throw new IOException("Expected 5 parts from split /proc/${pid}/status output, got " + parts.length); + } + } + } + if (uid < 0) { + throw new IOException("Unable to determine UID from /proc/${pid}/status"); + } + return uid; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/UserNameUtilImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,72 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.linux; + +import java.io.IOException; + +import com.redhat.thermostat.common.portability.UserNameLookupException; +import com.redhat.thermostat.common.portability.UserNameUtil; +import com.redhat.thermostat.shared.config.NativeLibraryResolver; + +public class UserNameUtilImpl implements UserNameUtil { + + static { + String lib = NativeLibraryResolver.getAbsoluteLibraryPath("UserNameUtilWrapper"); + System.load(lib); + } + + public String getUserName(long uid) throws UserNameLookupException { + String username = null; + if (uid >= 0) { + try { + // getUserName0 may throw IOException. We catch it here and + // throw a more specific exception in order to avoid API + // leakage. This exception is then dealt with in the caller of + // this method rather than here. This free's us from using the + // logger in a JNI class. + username = getUserName0(uid); + } catch (IOException e) { + throw new UserNameLookupException(e); + } + } + return username; + } + + private native String getUserName0(long uid) throws IOException; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,254 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.windows; + +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.shared.config.NativeLibraryResolver; +import com.redhat.thermostat.shared.config.OS; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +/** + * Utility class to access Windows native code + */ +public class WindowsHelperImpl { + + private static final Logger logger = LoggingUtils.getLogger(WindowsHelperImpl.class); + + public static WindowsHelperImpl INSTANCE; + + /* + // from MemoryStatusEx (8 values) + DWORD dwMemoryLoad; + DWORDLONG ullTotalPhys; + DWORDLONG ullAvailPhys; + DWORDLONG ullTotalPageFile; + DWORDLONG ullAvailPageFile; + DWORDLONG ullTotalVirtual; + DWORDLONG ullAvailVirtual; + DWORDLONG ullAvailExtendedVirtual; + + // from PERFORMANCE_INFORMATION (13 values) + SIZE_T CommitTotal; + SIZE_T CommitLimit; + SIZE_T CommitPeak; + SIZE_T PhysicalTotal; + SIZE_T PhysicalAvailable; + SIZE_T SystemCache; + SIZE_T KernelTotal; + SIZE_T KernelPaged; + SIZE_T KernelNonpaged; + SIZE_T PageSize; + DWORD HandleCount; + DWORD ProcessCount; + DWORD ThreadCount; + */ + + static { + if (OS.IS_WINDOWS) { + String lib = NativeLibraryResolver.getAbsoluteLibraryPath("WindowsHelperWrapper"); + try { + System.load(lib); + INSTANCE = new WindowsHelperImpl(); + } catch (UnsatisfiedLinkError e) { + logger.severe("Could not load WindowsHelperImpl DLL:" + lib); + INSTANCE = null; + // do not throw here, because you'll get a NoClassDefFound thrown when running other tests that Mock this class + } + } else { + INSTANCE = null; + } + } + + private WindowsHelperImpl() { + } + // local host-wide information + + public String getHostName() { + return getHostName0(true); + } + + public String getOSName() { + return System.getProperty("os.name"); + } + + public String getOSVersion() { + final long info[] = new long[3]; // major, minor, build + getOSVersion0(info); + return "" + info[0] + "" + info[1] + " (Build " + info[2] + ")"; + } + + public String getCPUModel() { + return getCPUString0(); + } + + public int getCPUCount() { + return getCPUCount0(); + } + + public long getTotalMemory() { + final long info[] = getMemoryInfo(); + return info[1]; // totalPhysical + } + + long[] getMemoryInfo() { + final long[] mi = new long[8]; + getGlobalMemoryStatus0(mi); + return mi; + } + + private long[] getPerformanceInfo() { + final long[] mi = new long[13]; + getPerformanceInfo0(mi); + return mi; + } + + public long getClockTicksPerSecond() { + // we "know" this is 10E7 (units from getProcessStat) + // but calculate it anyways from current process + final long[] info = INSTANCE.getProcessCPUInfo(0); + return info[4]; + } + + // local process-specific information + + public boolean exists(int pid) { + final long hnd = getLimitedProcessHandle0(pid); + if (hnd != 0) { + closeHandle0(hnd); + } + return hnd != 0; + } + + public String getUserName(int pid) { + return getUserName0(pid,true); + } + + public int getUid(int pid) { + final String sid = getProcessSID0(pid); + if (sid == null) { + return -1; + } + final int idx = sid.lastIndexOf('-'); + final String uidStr = sid.substring(idx+1); + return Integer.parseInt(uidStr); + } + + public Map<String, String> getEnvironment(int pid) { + // the environment is returned as a 1D array of alternating env names and values + final String[] envArray = getEnvironment0(pid); + if (envArray == null || envArray.length == 0) { + return Collections.emptyMap(); + } + + if (envArray.length % 2 != 0) { + throw new AssertionError("environment array length not even"); + } + + final Map<String, String> env = new HashMap<>(envArray.length/2); + for (int i = 0; i < envArray.length / 2; i++) { + env.put(envArray[i * 2], envArray[i * 2 + 1]); + } + return env; + } + + /** + * fetch process counters + * @param pid process id + * @return long[] working set size, user time, kernel time, (todo: elapsed time), ticks per second + */ + long[] getProcessCPUInfo(int pid) { + final long[] info = new long[5]; + getProcessInfo0(pid, info); + return info; + } + + long[] getProcessMemInfo(int pid) { + final long[] info = new long[5]; + getProcessInfo0(pid, info); + return info; + } + + long[] getProcessIOInfo(int pid) { + final long info[] = new long[6]; + getProcessIOInfo0(pid,info); + return info; + } + + public long getProcessHandle(int pid) { + return getProcessHandle0(pid); + } + + public void closeHandle(long handle) { + closeHandle0(handle); + } + + public boolean terminateProcess(int pid) { + return terminateProcess0(pid,0, -1); + } + + public boolean terminateProcess(int pid, boolean wait) { + return terminateProcess0(pid,0, 0); + } + + public boolean terminateProcess(int pid, int exitcode, int waitMillis) { + return terminateProcess0(pid, exitcode, waitMillis); + } + + private static native String getHostName0(boolean prependDomain); + private static native void getOSVersion0(long[] versionAndBuild); + private static native boolean getGlobalMemoryStatus0(long[] info); + private static native boolean getPerformanceInfo0(long[] info); + private static native String getCPUString0(); + private static native int getCPUCount0(); + private static native long queryPerformanceFrequency0(); + + private static native String getProcessSID0(int pid); + private static native String getUserName0(int pid, boolean prependDomain); + private static native String[] getEnvironment0(int pid); + private static native boolean getProcessInfo0(int pid, long[] info); + private static native boolean getProcessIOInfo0(int pid, long[] info); + + private static native long getCurrentProcessHandle0(); + private static native long getProcessHandle0(int pid); + private static native long getLimitedProcessHandle0(int pid); + private static native void closeHandle0(long handle); + private static native boolean terminateProcess0(int pid, int exitCode, int waitMillis); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHostImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,86 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.windows; + +import com.redhat.thermostat.common.portability.PortableHost; +import com.redhat.thermostat.common.portability.PortableMemoryStat; + +public class WindowsHostImpl implements PortableHost { + + public static final WindowsHostImpl INSTANCE = new WindowsHostImpl(); + private static final WindowsHelperImpl helper = WindowsHelperImpl.INSTANCE; + + @Override + public String getHostName() { + return helper.getHostName(); + } + + @Override + public String getOSName() { + return helper.getOSName(); + } + + @Override + public String getOSVersion() { + return helper.getOSVersion(); + } + + @Override + public String getCPUModel() { + return helper.getCPUModel(); + } + + @Override + public int getCPUCount() { + return helper.getCPUCount(); + } + + @Override + public long getTotalMemory() { + return helper.getTotalMemory(); + } + + @Override + public long getClockTicksPerSecond() { + return helper.getClockTicksPerSecond(); + } + + @Override + public PortableMemoryStat getMemoryStat() { + return new WindowsMemoryStat(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsMemoryStat.java Mon Jan 23 10:11:31 2017 -0500 @@ -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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.windows; + +import com.redhat.thermostat.common.portability.PortableMemoryStat; + +class WindowsMemoryStat extends PortableMemoryStat { + + WindowsMemoryStat() { + this(WindowsHelperImpl.INSTANCE.getMemoryInfo()); + } + + private WindowsMemoryStat(final long[] info) { + super(System.currentTimeMillis(), info[1], info[2], 0, 0, info[3], info[4], 0); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.windows; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessStat; +import com.redhat.thermostat.common.portability.PortableVmIoStat; + +import java.util.Map; + +public class WindowsProcessImpl implements PortableProcess { + + public static final WindowsProcessImpl INSTANCE = new WindowsProcessImpl(); + private static final WindowsHelperImpl helper = WindowsHelperImpl.INSTANCE; + + @Override + public boolean exists(int pid) { + return helper.exists(pid); + } + + @Override + public String getUserName(int pid) { + return helper.getUserName(pid); + } + + @Override + public int getUid(int pid) { + return helper.getUid(pid); + } + + @Override + public Map<String, String> getEnvironment(int pid) { + return helper.getEnvironment(pid); + } + + @Override + public PortableProcessStat getProcessStat(int pid) { + final long[] info = helper.getProcessCPUInfo(pid); + final long utime = info[1]; + final long stime = info[2]; + return new PortableProcessStat(pid, utime, stime); + } + + @Override + public PortableVmIoStat getVmIoStat(Clock clock, int pid) { + return new WindowsVmIoStat(clock, pid); + } + + @Override + public boolean terminateProcess(int pid) { + return helper.terminateProcess(pid); + } + + @Override + public boolean terminateProcess(int pid, boolean wait) { + return helper.terminateProcess(pid, wait); + } + + @Override + public boolean terminateProcess(int pid, int exitcode, int waitMillis) { + return helper.terminateProcess(pid, exitcode, waitMillis); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsUserInfoBuilderImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.windows; + +import com.redhat.thermostat.common.portability.PortableProcessImpl; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.utils.LoggingUtils; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Build User information via Windows helper classes + */ +public class WindowsUserInfoBuilderImpl implements ProcessUserInfoBuilder { + + private final PortableProcess procHelper; + + private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo(); + private static final Logger logger = LoggingUtils.getLogger(WindowsUserInfoBuilderImpl.class); + + public WindowsUserInfoBuilderImpl() { + this(PortableProcessImpl.INSTANCE); + } + + WindowsUserInfoBuilderImpl(PortableProcess helper) { + this.procHelper = helper; + } + + @Override + public ProcessUserInfo build(int pid) { + ProcessUserInfo info = NON_EXISTENT_USER; + try { + final long uid = procHelper.getUid(pid); + final String name = procHelper.getUserName(pid); + info = new ProcessUserInfo(uid, name); + } catch (Exception e) { + logger.log(Level.WARNING, "Unable to read user info for " + pid, e); + } + + return info; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsVmIoStat.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,51 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.windows; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.portability.PortableVmIoStat; + +class WindowsVmIoStat extends PortableVmIoStat { + + WindowsVmIoStat(Clock clock, int pid) { + this(clock, WindowsHelperImpl.INSTANCE.getProcessIOInfo(pid)); + } + + private WindowsVmIoStat(Clock clock, final long info[]) { + super(clock.getRealTimeMillis(), info[0], info[1], info[2], info[3]); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/linux/ProcDataSource.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,125 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.linux; + +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; + +/** + * Wrapper for files under {@code /proc/}. See proc(5) for details about this. + * + * This class is inherently unportable, but a _lot_ of Linux code would need refactoring + * before it can be unexported from the portability package. + * + * Note that different Unix-like OSs may or may not have a /proc (and the format may be different) + * for example Darwin/OSX doesn't have /proc + */ +public class ProcDataSource { + + private static final String LOAD_FILE = "/proc/loadavg"; + private static final String STAT_FILE = "/proc/stat"; + private static final String MEMINFO_FILE = "/proc/meminfo"; + private static final String CPUINFO_FILE = "/proc/cpuinfo"; + + private static final String PID_ENVIRON_FILE = "/proc/${pid}/environ"; + private static final String PID_IO_FILE = "/proc/${pid}/io"; + private static final String PID_STAT_FILE = "/proc/${pid}/stat"; + private static final String PID_STATUS_FILE = "/proc/${pid}/status"; + + /** + * Returns a reader for /proc/cpuinfo + */ + public Reader getCpuInfoReader() throws IOException { + return new FileReader(CPUINFO_FILE); + } + + /** + * Returns a reader for /proc/loadavg + */ + public Reader getCpuLoadReader() throws IOException { + return new FileReader(LOAD_FILE); + } + + /** + * Returns a reader for /proc/stat. Kernel/System statistics. + */ + public Reader getStatReader() throws IOException { + return new FileReader(STAT_FILE); + } + + /** + * Returns a reader for /proc/meminfo + */ + public Reader getMemInfoReader() throws IOException { + return new FileReader(MEMINFO_FILE); + } + + /** + * Returns a reader for /proc/$PID/environ + */ + public Reader getEnvironReader(int pid) throws IOException { + return new FileReader(getPidFile(PID_ENVIRON_FILE, pid)); + } + + /** + * Returns a reader for /proc/$PID/io + */ + public Reader getIoReader(int pid) throws IOException { + return new FileReader(getPidFile(PID_IO_FILE, pid)); + } + + /** + * Returns a reader for /proc/$PID/stat + */ + public Reader getStatReader(int pid) throws IOException { + return new FileReader(getPidFile(PID_STAT_FILE, pid)); + } + + /** + * Returns a reader for /proc/$PID/status + */ + public Reader getStatusReader(int pid) throws IOException { + return new FileReader(getPidFile(PID_STATUS_FILE, pid)); + } + + private String getPidFile(String fileName, int pid) { + return fileName.replace("${pid}", Integer.toString(pid)); + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/package-info.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,41 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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. + */ + + +/** + * Utilities to help with username lookups + */ +package com.redhat.thermostat.common.portability;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/native/HostName.c Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,65 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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. + */ + +#include "com_redhat_thermostat_common_portability_HostName.h" + +#include <jni.h> +#include <unistd.h> +#include <string.h> + +#if !defined(_WIN32) +# include <netdb.h> +#else // windows +# include <winsock2.h> +#endif + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif /* NI_MAXHOST */ + +JNIEXPORT jstring JNICALL +Java_com_redhat_thermostat_common_portability_HostName_getHostName + (JNIEnv *env, jclass HostNameClass) +{ + char hostname[NI_MAXHOST]; + memset(hostname, 0, sizeof(hostname)); + + if (gethostname(hostname, sizeof(hostname)) == 0) { + return (*env)->NewStringUTF(env, hostname); + } + return NULL; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/native/UserNameUtilImpl.c Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,112 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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. + */ + +#include "com_redhat_thermostat_common_portability_internal_linux_UserNameUtilImpl.h" + +#include <jni.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +#if !defined(_WIN32) +# include <pwd.h> +#else // windows +#endif + +static jint throw_IOException(JNIEnv *env, const char *message) { + const char *class_name = "java/io/IOException"; + jclass class = (*env)->FindClass(env, class_name); + if (class == NULL) { + return -1; + } + return (*env)->ThrowNew(env, class, message); +} + +#if !defined(_WIN32) + +JNIEXPORT jstring JNICALL +Java_com_redhat_thermostat_common_portability_internal_linux_UserNameUtilImpl_getUserName0 + (JNIEnv *env, jclass ProcessUserInfoBuilderClass, jlong uid) { + size_t bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize < 0) { + throw_IOException(env, "Unable to retrieve recommended buffer size from sysconf"); + return NULL; + } + + char *buf = malloc(bufsize * sizeof(char)); + if (!buf) { + throw_IOException(env, "Unable to allocate buffer for username"); + return NULL; + } + + struct passwd pwd; + struct passwd *ret; + int rc = getpwuid_r(uid, &pwd, buf, bufsize, &ret); + if (rc) { + // Error occurred + const char *error_message = strerror(rc); + throw_IOException(env, error_message); + free(buf); + return NULL; + } + if (!ret) { + // No username found + char err_buf[128]; // Large enough for even the largest UIDs + snprintf(err_buf, sizeof(err_buf), "Username not found for uid: %ld", uid); + throw_IOException(env, err_buf); + free(buf); + return NULL; + } + + jstring name = (*env)->NewStringUTF(env, pwd.pw_name); + free(buf); + return name; +} + +#else // Windows +JNIEXPORT jstring JNICALL +Java_com_redhat_thermostat_common_portability_internal_linux_UserNameUtilImpl_getUserName0 + (JNIEnv *env, jclass ProcessUserInfoBuilderClass, jlong uid) { + + // TODO + throw_IOException(env, "UserNameUtilImpl.getUserName() no yet implemented on Windows"); + jstring name = (*env)->NewStringUTF(env, "xxxuserxxx"); + return name; +} +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/native/WindowsHelperImpl.c Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,614 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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. + */ + +#include "com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl.h" +#include <jni.h> +#include <unistd.h> +#include <string.h> + +#if !defined(_WIN32) +# include <netdb.h> +#else // windows +# include <winsock2.h> +# include <psapi.h> +# include <intrin.h> +#endif + +#define MAX_NAME 256 +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif /* NI_MAXHOST */ + +#if defined(DEBUG) +static void testLength(JNIEnv* env, jlongArray array, int minLength) { + // sanity test + jsize len = (*env)->GetArrayLength(env, array); + assert(len >= minLength); +} +#else +static void testLength(JNIEnv* env, jlongArray array, int minLength) {} +#endif + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getHostName0 + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getHostName0 + (JNIEnv *env, jclass winHelperClass, jboolean prependDomain) +{ + char hostname[NI_MAXHOST]; + memset(hostname, 0, sizeof(hostname)); + + if (gethostname(hostname, sizeof(hostname)) == 0) { + return (*env)->NewStringUTF(env, hostname); + } + return NULL; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getOSVersion0 + * Signature: ([J)V + */ +JNIEXPORT void JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getOSVersion0 + (JNIEnv *env, jclass winHelperClass, jlongArray array) +{ + testLength(env, array, 3); + + // Get the element pointer + jlong* data = (*env)->GetLongArrayElements(env, array, 0); + + OSVERSIONINFOEX vinfo; + vinfo.dwOSVersionInfoSize = sizeof(vinfo); + GetVersionEx(&vinfo); + data[0] = vinfo.dwMajorVersion; + data[1] = vinfo.dwMinorVersion; + data[2] = vinfo.dwBuildNumber; + + (*env)->ReleaseLongArrayElements(env, array, data, 0); +} + + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getGlobalMemoryStatus0 + * Signature: ([J)V + */ +JNIEXPORT boolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getGlobalMemoryStatus0 + (JNIEnv *env, jclass winHelperClass, jlongArray array) +{ + testLength(env, array, 8); + + // Get the element pointer + jlong* data = (*env)->GetLongArrayElements(env, array, 0); + + // get the memory info + MEMORYSTATUSEX statex; + statex.dwLength = sizeof(statex); + GlobalMemoryStatusEx(&statex); + data[0] = statex.dwMemoryLoad; + data[1] = statex.ullTotalPhys; + data[2] = statex.ullAvailPhys; + data[3] = statex.ullTotalPageFile; + data[4] = statex.ullAvailPageFile; + data[5] = statex.ullTotalVirtual; + data[6] = statex.ullAvailVirtual; + data[7] = statex.ullAvailExtendedVirtual; + + (*env)->ReleaseLongArrayElements(env, array, data, 0); + return TRUE; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getPerformanceInfo0 + * Signature: ([J)V + */ +JNIEXPORT boolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getPerformanceInfo0 + (JNIEnv *env, jclass winHelperClass, jlongArray array) +{ + testLength(env, array, 13); + + // Get the element pointer + jlong* data = (*env)->GetLongArrayElements(env, array, 0); + + /** + // from PERFORMANCE_INFORMATION (13 values) + SIZE_T CommitTotal; + SIZE_T CommitLimit; + SIZE_T CommitPeak; + SIZE_T PhysicalTotal; + SIZE_T PhysicalAvailable; + SIZE_T SystemCache; + SIZE_T KernelTotal; + SIZE_T KernelPaged; + SIZE_T KernelNonpaged; + SIZE_T PageSize; + DWORD HandleCount; + DWORD ProcessCount; + DWORD ThreadCount; + */ + + // get the memeory info + PERFORMANCE_INFORMATION statex; + statex.cb = sizeof(statex); + GetPerformanceInfo(&statex, statex.cb); + data[0] = statex.CommitTotal; + data[1] = statex.CommitLimit; + data[2] = statex.CommitPeak; + data[3] = statex.PhysicalTotal; + data[4] = statex.PhysicalAvailable; + data[5] = statex.SystemCache; + data[6] = statex.KernelTotal; + data[7] = statex.KernelPaged; + data[8] = statex.KernelNonpaged; + data[9] = statex.PageSize; + data[10] = statex.HandleCount; + data[11] = statex.ProcessCount; + data[12] = statex.ThreadCount; + + (*env)->ReleaseLongArrayElements(env, array, data, 0); + return TRUE; +} + + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getCPUString0 + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getCPUString0 + (JNIEnv *env, jclass winHelperClass) +{ + // Get extended ids. + int CPUInfo[4] = {-1}; + __cpuid(CPUInfo, 0x80000000); + unsigned int nExIds = CPUInfo[0]; + + // Get the information associated with each extended ID. + char CPUBrandString[0x40] = { 0 }; + for( unsigned int i=0x80000000; i<=nExIds; ++i) + { + __cpuid(CPUInfo, i); + + // Interpret CPU brand string and cache information. + if (i == 0x80000002) + { + memcpy( CPUBrandString, + CPUInfo, + sizeof(CPUInfo)); + } + else if( i == 0x80000003 ) + { + memcpy( CPUBrandString + 16, + CPUInfo, + sizeof(CPUInfo)); + } + else if( i == 0x80000004 ) + { + memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo)); + } + } + return (*env)->NewStringUTF(env, CPUBrandString); + +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getCPUCount0 + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getCPUCount0 + (JNIEnv *env, jclass winHelperClass) +{ + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + + return sysinfo.dwNumberOfProcessors; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: queryPerformanceFrequency0 + * Signature: ()I + */ +JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_queryPerformanceFrequency0 + (JNIEnv *env, jclass winHelperClass) +{ + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + + return (jlong)(freq.QuadPart); +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getProcessSID0 + * Signature: (I)I + */ +JNIEXPORT jstring JNICALL +Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getProcessSID0 + (JNIEnv *env, jclass winHelperClass, jint pid) +{ + HANDLE hProcess; + + hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid ); + if (NULL == hProcess) + return NULL; + + HANDLE hToken = NULL; + + if( !OpenProcessToken( hProcess, TOKEN_QUERY, &hToken ) ) { + CloseHandle( hProcess ); + return NULL; + } + + DWORD dwSize = MAX_NAME; + DWORD dwLength = 0; + PTOKEN_USER ptu = NULL; + + if (!GetTokenInformation( + hToken, // handle to the access token + TokenUser, // get information about the token's groups + (LPVOID) ptu, // pointer to PTOKEN_USER buffer + 0, // size of buffer + &dwLength // receives required buffer size + )) { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + CloseHandle( hToken ); + CloseHandle( hProcess ); + return NULL; + } + + ptu = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); + + if (ptu == NULL) { + CloseHandle( hToken ); + CloseHandle( hProcess ); + return NULL; + } + } + + if (!GetTokenInformation( + hToken, // handle to the access token + TokenUser, // get information about the token's groups + (LPVOID) ptu, // pointer to PTOKEN_USER buffer + dwLength, // size of buffer + &dwLength // receives required buffer size + )) { + if (ptu != NULL) { + HeapFree(GetProcessHeap(), 0, (LPVOID)ptu); + } + CloseHandle( hToken ); + CloseHandle( hProcess ); + return NULL; + } + + LPWSTR stringSid; + ConvertSidToStringSidW( ptu->User.Sid, &stringSid ); + jstring s = (*env)->NewString(env, (const jchar *)stringSid, (jsize)wcslen(stringSid)); + + LocalFree(stringSid); + + if (ptu != NULL) { + HeapFree(GetProcessHeap(), 0, (LPVOID)ptu); + } + CloseHandle( hToken ); + CloseHandle( hProcess ); + return s; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getUserName0 + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getUserName0 + (JNIEnv *env, jclass winHelperClass, jint pid, jboolean prependDomain) +{ + HANDLE hProcess; + + hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid ); + if (NULL == hProcess) + return NULL; + + HANDLE hToken = NULL; + + if( !OpenProcessToken( hProcess, TOKEN_QUERY, &hToken ) ) { + CloseHandle( hProcess ); + return NULL; + } + + DWORD dwSize = MAX_NAME; + DWORD dwLength = 0; + PTOKEN_USER ptu = NULL; + + if (!GetTokenInformation( + hToken, // handle to the access token + TokenUser, // get information about the token's groups + (LPVOID) ptu, // pointer to PTOKEN_USER buffer + 0, // size of buffer + &dwLength // receives required buffer size + )) { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + CloseHandle( hToken ); + CloseHandle( hProcess ); + return NULL; + } + + ptu = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); + + if (ptu == NULL) { + CloseHandle( hToken ); + CloseHandle( hProcess ); + return NULL; + } + } + + if (!GetTokenInformation( + hToken, // handle to the access token + TokenUser, // get information about the token's groups + (LPVOID) ptu, // pointer to PTOKEN_USER buffer + dwLength, // size of buffer + &dwLength // receives required buffer size + )) { + if (ptu != NULL) { + HeapFree(GetProcessHeap(), 0, (LPVOID)ptu); + } + CloseHandle( hToken ); + CloseHandle( hProcess ); + return NULL; + } + + SID_NAME_USE SidType; + wchar_t lpName[MAX_NAME]; + wchar_t lpDomain[MAX_NAME*2 + 1]; // room for '\' + lpName + jstring s = NULL; + + if( !LookupAccountSidW( NULL , ptu->User.Sid, lpName, &dwSize, lpDomain, &dwSize, &SidType ) ) + { + DWORD dwResult = GetLastError(); + if( dwResult == ERROR_NONE_MAPPED ) + strcpy (lpName, "NONE_MAPPED" ); + else + { + printf("LookupAccountSid Error %u\n", GetLastError()); + } + } + else + { + if (prependDomain) { + wcscat(lpDomain, L"\\"); + wcscat(lpDomain, lpName); + s = (*env)->NewString(env, (const jchar *)lpDomain, (jsize)wcslen(lpDomain)); + } + else { + s = (*env)->NewString(env, (const jchar *)lpName, (jsize)wcslen(lpName)); + } + } + + if (ptu != NULL) { + HeapFree(GetProcessHeap(), 0, (LPVOID)ptu); + } + CloseHandle( hToken ); + CloseHandle( hProcess ); + return s; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getEnvironment0 + * Signature: ()[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL +Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getEnvironment0 + (JNIEnv *env, jclass winHelperClass, jint pid) +{ + // TODO - implement this stub - not eay (have to open the process memory and poke around) + // for now, return an empty array + jobjectArray ret = (jobjectArray)(*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, "")); + return ret; +} + +static unsigned __int64 convertFileTimeToInt64( const FILETIME * pFileTime ) +{ + ULARGE_INTEGER largeInt; + + largeInt.LowPart = pFileTime->dwLowDateTime; + largeInt.HighPart = pFileTime->dwHighDateTime; + + return largeInt.QuadPart; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getProcessMemoryInfo0 + * Signature: (I[J)V + */ +JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getProcessInfo0 + (JNIEnv *env, jclass winHelperClass, jint pid, jlongArray array) +{ + testLength(env, array, 4); + + HANDLE hProcess; + PROCESS_MEMORY_COUNTERS pmc; + + hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid ); + if (NULL == hProcess) + return FALSE; + + // Get the element pointer + jlong* data = (*env)->GetLongArrayElements(env, array, 0); + + pmc.cb = sizeof(pmc); + if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) { + data[0] = pmc.WorkingSetSize; + } + else { + (*env)->ReleaseLongArrayElements(env, array, data, 0); + return FALSE; + } + + FILETIME creationTime; + FILETIME exitTime; + FILETIME kernelTime; + FILETIME userTime; + + if ( GetProcessTimes( hProcess, &creationTime, &exitTime, &kernelTime, &userTime ) ) { + // times returned from GetProcessTimes() are in 100-nanosecond units. + data[1] = convertFileTimeToInt64(&userTime); + data[2] = convertFileTimeToInt64(&kernelTime); + data[3] = convertFileTimeToInt64(&creationTime); + data[4] = 10000000; // 100 nanonseconds is this many ticks per second + } + + CloseHandle(hProcess); + + (*env)->ReleaseLongArrayElements(env, array, data, 0); + return TRUE; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getProcessIOInfo0 + * Signature: (I[J)V + */ +JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getProcessIOInfo0 + (JNIEnv *env, jclass winHelperClass, jint pid, jlongArray array) +{ + testLength(env, array, 6); + + HANDLE hProcess; + IO_COUNTERS iocounters; + + hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid ); + if (NULL == hProcess) + return FALSE; + + BOOL rc = GetProcessIoCounters( hProcess, &iocounters ); + if (!rc) { + CloseHandle(hProcess); + return FALSE; + } + + // Get the element pointer + jlong* data = (*env)->GetLongArrayElements(env, array, 0); + + data[0] = iocounters.ReadOperationCount; + data[1] = iocounters.WriteOperationCount; + data[2] = iocounters.ReadTransferCount; + data[3] = iocounters.WriteTransferCount; + data[4] = iocounters.OtherOperationCount; + data[5] = iocounters.OtherTransferCount; + + (*env)->ReleaseLongArrayElements(env, array, data, 0); + CloseHandle(hProcess); + return TRUE; +} + + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getProcessHandle0 + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getCurrentProcessHandle0 + (JNIEnv *env, jclass winHelperClass) { + + HANDLE hProcess; + hProcess = GetCurrentProcess(); + return (jlong) hProcess; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getProcessHandle0 + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getProcessHandle0 + (JNIEnv *env, jclass winHelperClass, jint pid) { + + HANDLE hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid ); + return (jlong) hProcess; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getLimitedProcessHandle0 + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getLimitedProcessHandle0 + (JNIEnv *env, jclass winHelperClass, jint pid) { + + HANDLE hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid ); + return (jlong) hProcess; +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: closeHandle0 + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_closeHandle0 + (JNIEnv *env, jclass winHelperClass, jlong handle){ + + CloseHandle((HANDLE)handle); +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: terminateProcess0 + * Signature: (IIB)V + */ +JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_terminateProcess0 + (JNIEnv *env, jclass winHelperClass, jint pid, jint exitCode, jint waitMillis) { + + HANDLE hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid ); + if (!hProcess) { + return FALSE; + } + TerminateProcess(hProcess, (unsigned int)exitCode); + if (waitMillis >= 0) { + WaitForSingleObject(hProcess, waitMillis); + } + CloseHandle(hProcess); + return TRUE; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/ProcessCheckerTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,74 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; + +import com.redhat.thermostat.common.portability.ProcessChecker; +import org.junit.Test; + +public class ProcessCheckerTest { + + private static final int SOME_PID = 80980; + + @Test + public void testProcessExists() { + basicTest(true); + } + + @Test + public void testProcessNotExisting() { + basicTest(false); + } + + private void basicTest(boolean expected) { + final File baseFile = mock(File.class); + when(baseFile.exists()).thenReturn(expected); + ProcessChecker process = new ProcessChecker() { + @Override + File mapToFile(int pid) { + assertEquals(SOME_PID, pid); + return baseFile; + } + }; + assertEquals(expected, process.exists(SOME_PID)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/ActivatorTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.File; + +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.common.portability.UserNameUtil; +import com.redhat.thermostat.shared.config.CommonPaths; +import com.redhat.thermostat.shared.config.NativeLibraryResolver; +import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.common.portability.internal.linux.UserNameUtilImpl; + +public class ActivatorTest { + + private StubBundleContext context; + private ServiceRegistration ipcReg; + + @Before + public void setup() { + context = new StubBundleContext(); + CommonPaths paths = mock(CommonPaths.class); + when(paths.getSystemNativeLibsRoot()).thenReturn(new File("target")); + when(paths.getUserAgentAuthConfigFile()).thenReturn(new File("not.exist.does.not.matter")); + NativeLibraryResolver.setCommonPaths(paths); + } + + @Test + public void verifyServiceIsRegistered() throws Exception { + Activator activator = new Activator(); + activator.start(context); + + assertTrue(context.isServiceRegistered(UserNameUtil.class.getName(), UserNameUtilImpl.class)); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/SysConfTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,52 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal; + +import static org.junit.Assert.assertTrue; + +import com.redhat.thermostat.common.portability.SysConf; +import org.junit.Test; + +public class SysConfTest { + + @Test + public void test() { + long ticksPerSecond = SysConf.getClockTicksPerSecond(); + assertTrue(ticksPerSecond >= 1); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessUserInfoBuilderImplTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.linux; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.StringReader; + +import com.redhat.thermostat.common.portability.UserNameLookupException; +import com.redhat.thermostat.common.portability.UserNameUtil; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; + +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import org.junit.Test; + +import com.redhat.thermostat.common.tools.ApplicationException; + +public class LinuxProcessUserInfoBuilderImplTest { + + @Test + public void testBuild() throws UserNameLookupException, IOException, ApplicationException { + StringReader reader = new StringReader("Uid: 2000 2000 2000 2000"); + ProcDataSource source = mock(ProcDataSource.class); + UserNameUtil util = mock(UserNameUtil.class); + when(util.getUserName(2000)).thenReturn("myUser"); + when(source.getStatusReader(anyInt())).thenReturn(reader); + ProcessUserInfoBuilder builder = new LinuxProcessUserInfoBuilderImpl(source, util); + ProcessUserInfo info = builder.build(0); + + assertEquals(2000, info.getUid()); + assertEquals("myUser", info.getUsername()); + } + + @Test + public void testBuildErrorUid() throws IOException, ApplicationException { + StringReader reader = new StringReader(""); + ProcDataSource source = mock(ProcDataSource.class); + UserNameUtil util = mock(UserNameUtil.class); + when(source.getStatusReader(anyInt())).thenReturn(reader); + ProcessUserInfoBuilder builder = new LinuxProcessUserInfoBuilderImpl(source, util); + ProcessUserInfo info = builder.build(0); + + assertEquals(-1, info.getUid()); + assertEquals(null, info.getUsername()); + } + + @Test + public void testBuildErrorUsername() throws IOException, UserNameLookupException, ApplicationException { + StringReader reader = new StringReader("Uid: 2000 2000 2000 2000"); + ProcDataSource source = mock(ProcDataSource.class); + UserNameUtil util = mock(UserNameUtil.class); + when(util.getUserName(2000)).thenReturn(null); + when(source.getStatusReader(anyInt())).thenReturn(reader); + ProcessUserInfoBuilder builder = new LinuxProcessUserInfoBuilderImpl(source, util); + ProcessUserInfo info = builder.build(0); + + assertEquals(2000, info.getUid()); + assertEquals(null, info.getUsername()); + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImplTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.windows; + +import com.redhat.thermostat.shared.config.OS; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.Map; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * These tests are disabled until we get the DLL path issues sorted out + * TODO - These tests currently fail on Windows because the helper DLL isn't on the execution path + */ + +@Ignore +public class WindowsHelperImplTest { + + @Test + public void loadNativeLib() { + Assume.assumeTrue(OS.IS_WINDOWS); + final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE; + Assert.assertNotNull(impl); + } + + @Test + public void testGetHostInfo() { + Assume.assumeTrue(OS.IS_WINDOWS); + final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE; + Assert.assertNotNull(impl); + assertContainsData(impl.getHostName()); + assertContainsData(impl.getOSName()); + Assert.assertTrue(impl.getOSName().toLowerCase().contains("win")); + assertContainsData(impl.getOSVersion()); + assertContainsData(impl.getCPUModel()); + Assert.assertTrue(impl.getCPUCount() > 0); + Assert.assertTrue(impl.getTotalMemory() > 0); + } + + @Test + @Ignore + public void testGetProcessInfo() { + Assume.assumeTrue(OS.IS_WINDOWS); + final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE; + Assert.assertNotNull(impl); + int pid = /*TODO: retrieve current process identifier*/0; + assertContainsData(impl.getUserName(pid)); + Assert.assertTrue(impl.getUid(pid) >= 0); + Map<String,String> envMap = impl.getEnvironment(pid); + Assert.assertNotNull(envMap); + Assert.assertFalse(envMap.isEmpty()); + } + + private static void assertContainsData( final String s ) { + Assert.assertNotNull(s); + Assert.assertFalse(s.isEmpty()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessUserInfoBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,102 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.internal.windows; + +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.shared.config.OS; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Matchers; +import org.mockito.Mockito; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; + +/** + * test windows user info builder + */ +public class WindowsProcessUserInfoBuilderTest { + + private PortableProcess whelp; + + private static final String FAKE_USERNAME = "testuser"; + private static final int FAKE_PID = 4567; + private static final int FAKE_UID = 7652; + + @Before + public void setup() { + whelp = Mockito.mock(PortableProcess.class); + Mockito.when(whelp.getUserName(Matchers.anyInt())).thenReturn("badname"); + Mockito.when(whelp.getUserName(Matchers.eq(FAKE_PID))).thenReturn(FAKE_USERNAME); + Mockito.when(whelp.getUid(Matchers.anyInt())).thenReturn(11); + Mockito.when(whelp.getUid(Matchers.eq(FAKE_PID))).thenReturn(FAKE_UID); + } + + // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path + @Test + @Ignore + public void testSimpleBuild() { + Assume.assumeTrue(OS.IS_WINDOWS); + ProcessUserInfo info = new WindowsUserInfoBuilderImpl().build(FAKE_PID); + Assert.assertNotNull(info); + } + + @Test + public void testGetInfoFromGoodPid() { + final ProcessUserInfoBuilder ib = new WindowsUserInfoBuilderImpl(whelp); + final ProcessUserInfo hi = ib.build(FAKE_PID); + assertEquals(FAKE_USERNAME, hi.getUsername()); + assertEquals(FAKE_UID, hi.getUid()); + } + + @Test + public void testGetInfoFromBadPid() { + final ProcessUserInfoBuilder ib = new WindowsUserInfoBuilderImpl(whelp); + final ProcessUserInfo hi = ib.build(FAKE_PID+1); + Assert.assertNotSame(FAKE_USERNAME,hi.getUsername()); + Assert.assertNotSame(FAKE_UID, hi.getUid()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/linux/ProcDataSourceTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,114 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.common.portability.linux; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.io.Reader; + +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.shared.config.OS; +import org.junit.Assume; +import org.junit.Test; + +import com.redhat.thermostat.testutils.TestUtils; + +public class ProcDataSourceTest { + + @Test + public void testGetCpuInfoReader() throws IOException { + Assume.assumeTrue(OS.IS_UNIX); + Reader r = new ProcDataSource().getCpuInfoReader(); + assertNotNull(r); + } + + @Test + public void testGetCpuLoadReader() throws IOException { + Assume.assumeTrue(OS.IS_UNIX); + Reader r = new ProcDataSource().getCpuLoadReader(); + assertNotNull(r); + } + + @Test + public void testGetMemInfoReader() throws IOException { + Assume.assumeTrue(OS.IS_UNIX); + Reader r = new ProcDataSource().getMemInfoReader(); + assertNotNull(r); + } + + @Test + public void testGetStatReader() throws IOException { + Assume.assumeTrue(OS.IS_UNIX); + int pid = TestUtils.getProcessId(); + Reader r = new ProcDataSource().getStatReader(pid); + assertNotNull(r); + } + + @Test + public void testGetEnvironReader() throws IOException { + Assume.assumeTrue(OS.IS_UNIX); + int pid = TestUtils.getProcessId(); + Reader r = new ProcDataSource().getEnvironReader(pid); + assertNotNull(r); + } + + @Test + public void testIoReader() throws Exception { + Assume.assumeTrue(OS.IS_UNIX); + int pid = TestUtils.getProcessId(); + Reader r = new ProcDataSource().getIoReader(pid); + assertNotNull(r); + } + + @Test + public void testStatReader() throws Exception { + Assume.assumeTrue(OS.IS_UNIX); + int pid = TestUtils.getProcessId(); + Reader r = new ProcDataSource().getStatReader(pid); + assertNotNull(r); + } + + @Test + public void testStatusReader() throws Exception { + Assume.assumeTrue(OS.IS_UNIX); + int pid = TestUtils.getProcessId(); + Reader r = new ProcDataSource().getStatusReader(pid); + assertNotNull(r); + } +} +
--- a/distribution/assembly/core-assembly-windows.xml Fri Jan 20 10:48:09 2017 -0500 +++ b/distribution/assembly/core-assembly-windows.xml Mon Jan 23 10:11:31 2017 -0500 @@ -65,6 +65,7 @@ <include>com.redhat.thermostat:thermostat-agent-ipc-tcpsocket-client</include> <include>com.redhat.thermostat:thermostat-common-core</include> <include>com.redhat.thermostat:thermostat-common-command</include> + <include>com.redhat.thermostat:thermostat-common-portability</include> <include>com.redhat.thermostat:thermostat-process-handler</include> <include>com.redhat.thermostat:thermostat-storage-cli</include> <include>com.redhat.thermostat:thermostat-storage-mongodb</include>
--- a/distribution/assembly/core-assembly.xml Fri Jan 20 10:48:09 2017 -0500 +++ b/distribution/assembly/core-assembly.xml Mon Jan 23 10:11:31 2017 -0500 @@ -67,6 +67,7 @@ <include>com.redhat.thermostat:thermostat-agent-ipc-unixsocket-client</include> <include>com.redhat.thermostat:thermostat-common-core</include> <include>com.redhat.thermostat:thermostat-common-command</include> + <include>com.redhat.thermostat:thermostat-common-portability</include> <include>com.redhat.thermostat:thermostat-process-handler</include> <include>com.redhat.thermostat:thermostat-storage-cli</include> <include>com.redhat.thermostat:thermostat-storage-mongodb</include>
--- a/distribution/packaging/fedora/thermostat.spec Fri Jan 20 10:48:09 2017 -0500 +++ b/distribution/packaging/fedora/thermostat.spec Mon Jan 23 10:11:31 2017 -0500 @@ -573,8 +573,8 @@ "<groupId>com.github.jnr</groupId>" # Don't use maven-exec-plugin. We do things manually in order to avoid this -# additional dep. It's used in agent/core/pom.xml et.al. -%pom_remove_plugin org.codehaus.mojo:exec-maven-plugin agent/core +# additional dep. It's used in common/portability/pom.xml et.al. +%pom_remove_plugin org.codehaus.mojo:exec-maven-plugin common/portability %pom_remove_plugin org.codehaus.mojo:exec-maven-plugin keyring %pom_remove_plugin org.codehaus.mojo:exec-maven-plugin laf-utils @@ -694,6 +694,17 @@ src/main/java/com/redhat/thermostat/common/internal/LocaleResources.java \ src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java popd +pushd common/portability + mkdir -p target/classes + javac -cp ../../config/target/classes:../../annotations/target/classes:../../common/core/target/classes \ + -d target/classes \ + src/main/java/com/redhat/thermostat/common/portability/HostName.java \ + src/main/java/com/redhat/thermostat/common/portability/UserNameUtil.java \ + src/main/java/com/redhat/thermostat/common/portability/UserNameLookupException.java \ + src/main/java/com/redhat/thermostat/common/portability/internal/linux/UserNameUtilImpl.java + src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java + make all +popd pushd keyring mkdir -p target/classes javac -cp ../config/target/classes:../annotations/target/classes \ @@ -705,17 +716,6 @@ ./configure make all popd -pushd agent/core - mkdir -p target/classes - javac -cp ../../config/target/classes:../../annotations/target/classes:../../common/core/target/classes \ - -d target/classes \ - src/main/java/com/redhat/thermostat/agent/utils/hostname/HostName.java \ - src/main/java/com/redhat/thermostat/agent/utils/username/UserNameUtil.java \ - src/main/java/com/redhat/thermostat/agent/utils/username/UserNameLookupException.java \ - src/main/java/com/redhat/thermostat/agent/utils/windows/WindowsHelperImpl.java \ - src/main/java/com/redhat/thermostat/utils/username/internal/UserNameUtilImpl.java - make all -popd pushd laf-utils mkdir -p target/classes javac -cp ../config/target/classes \
--- a/distribution/pom.xml Fri Jan 20 10:48:09 2017 -0500 +++ b/distribution/pom.xml Mon Jan 23 10:11:31 2017 -0500 @@ -113,9 +113,9 @@ <target> <copy file="${main.basedir}/keyring/target/libGnomeKeyringWrapper.so" todir="${project.build.directory}/image/libs/native" /> - <copy file="${main.basedir}/agent/core/target/libHostNameWrapper.so" + <copy file="${main.basedir}/common/portability/target/libHostNameWrapper.so" todir="${project.build.directory}/image/libs/native" /> - <copy file="${main.basedir}/agent/core/target/libUserNameUtilWrapper.so" + <copy file="${main.basedir}/common/portability/target/libUserNameUtilWrapper.so" todir="${project.build.directory}/image/libs/native" /> <copy file="${main.basedir}/laf-utils/target/libGTKThemeUtils.so" todir="${project.build.directory}/image/libs/native" /> @@ -169,11 +169,11 @@ <configuration> <target> <!-- copy and rename the native libraries --> - <copy file="${main.basedir}/agent/core/target/HostNameWrapper.dll" + <copy file="${main.basedir}/common/portability/target/HostNameWrapper.dll" todir="${project.build.directory}/image/libs/native" /> - <copy file="${main.basedir}/agent/core/target/UserNameUtilWrapper.dll" + <copy file="${main.basedir}/common/portability/target/UserNameUtilWrapper.dll" todir="${project.build.directory}/image/libs/native" /> - <copy file="${main.basedir}/agent/core/target/WindowsHelperWrapper.dll" + <copy file="${main.basedir}/common/portability/target/WindowsHelperWrapper.dll" todir="${project.build.directory}/image/libs/native" /> </target> </configuration> @@ -587,6 +587,11 @@ <version>${project.version}</version> </dependency> <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-portability</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-process-handler</artifactId> <version>${project.version}</version>
--- a/distribution/windows/scripts/thermostat-agent-proxy.cmd Fri Jan 20 10:48:09 2017 -0500 +++ b/distribution/windows/scripts/thermostat-agent-proxy.cmd Mon Jan 23 10:11:31 2017 -0500 @@ -1,6 +1,6 @@ @echo off -:: Copyright 2016 Red Hat, Inc. +:: Copyright 2017 Red Hat, Inc. :: :: This file is part of Thermostat. :: @@ -36,6 +36,55 @@ setlocal -%~dp0\thermostat-common.cmd +if "%4"=="" goto usage +if not "%5"=="" goto usage + + goto skipfuncdefs + + :usage + echo "usage: %~f0 <pidOfTargetJvm> <userNameOfJvmOwner> <ipcConfigFile> <ipcServerName>" + exit /b 1 + + :skipfuncdefs + +set TARGET_PID=%1 +set TARGET_USER=%2 +set CONFIG_FILE=%3 +set IPC_SERVER_NAME=%4 + +:: Source thermostat-ipc-client-common from same directory as this script +:: Defines IPC_CLASSPATH variable with JARs necessary for the IPC service + +call %~dp0\thermostat-ipc-client-common.cmd +if not "%errorlevel%"=="0" exit /b %errorlevel% -echo thermostat-agent-proxy not implemented on Windows. +:: Ensure thermostat-ipc-client-common sourced correctly +if not defined IPC_CLASSPATH ( + echo "Classpath not properly defined for agent proxy" + exit /b 1 +) + +:: Need tools from the JVM +set TOOLS_JAR=%JAVA_HOME%\lib\tools.jar + +:: Additional JARs necessary for the agent proxy +set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-common-core-@project.version@.jar +set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-shared-config-@project.version@.jar +set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-agent-proxy-server-@project.version@.jar +set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\gson-@gson.version@.jar +set IPC_CLASSPATH=%TOOLS_JAR%;%IPC_CLASSPATH% + +set AGENT_PROXY_CLASS=com.redhat.thermostat.agent.proxy.server.AgentProxy + +:: Set this to remote debug +if defined THERMOSTAT_DEBUG ( + set DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=1082 +) + +:: Start server +:: within the server, consider adjusting toek priviledge to disable debug, etc +set CONFIG_FILE_ARG=-DipcConfigFile=%CONFIG_FILE% + +%JAVA% -cp %IPC_CLASSPATH% %CONFIG_FILE_ARG% %LOGGING_ARGS% %DEBUG_OPTS% %AGENT_PROXY_CLASS% %TARGET_PID% %IPC_SERVER_NAME% %TARGET_USER% + +
--- a/distribution/windows/scripts/thermostat-common.cmd Fri Jan 20 10:48:09 2017 -0500 +++ b/distribution/windows/scripts/thermostat-common.cmd Mon Jan 23 10:11:31 2017 -0500 @@ -1,6 +1,6 @@ @echo off -:: Copyright 2016 Red Hat, Inc. +:: Copyright 2017 Red Hat, Inc. :: :: This file is part of Thermostat. :: @@ -40,15 +40,15 @@ :: Duplicated in ThermostatVmMainLabelDecorator set THERMOSTAT_MAIN=com.redhat.thermostat.main.Thermostat +set jdk_home_candidate=@thermostat.jdk.home@ if not defined JAVA_HOME ( - set jdk_home_candidate="@thermostat.jdk.home@" if exist %jdk_home_candidate%\bin\javac.exe ( set JAVA_HOME=%jdk_home_candidate% ) else ( - :: Got likely a JRE, but thermostat expects a full JDK, try - :: one level up and hope this will work. We check - :: if JAVA_HOME is a valid value below. + rem Got likely a JRE, but thermostat expects a full JDK, try + rem one level up and hope this will work. We check + rem if JAVA_HOME is a valid value below. set JAVA_HOME=%jdk_home_candidate%\.. ) )
--- a/distribution/windows/scripts/thermostat-webservice.cmd Fri Jan 20 10:48:09 2017 -0500 +++ b/distribution/windows/scripts/thermostat-webservice.cmd Mon Jan 23 10:11:31 2017 -0500 @@ -1,6 +1,6 @@ @echo off -:: Copyright 2016 Red Hat, Inc. +:: Copyright 2017 Red Hat, Inc. :: :: This file is part of Thermostat. :: @@ -39,6 +39,7 @@ %~dp0\thermostat-common.cmd echo thermostat-webservice not implemented on Windows. +exit 1 set TOMCAT_DIR=tomcat
--- a/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilder.java Fri Jan 20 10:48:09 2017 -0500 +++ b/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilder.java Mon Jan 23 10:11:31 2017 -0500 @@ -41,7 +41,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.common.Clock; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.host.cpu.common.model.CpuStat; @@ -139,7 +139,7 @@ private long[] getCurrentCpuTicksWindows() { long[] values = new long[1]; - values[1] = clock.getMonotonicTimeNanos(); + values[0] = clock.getMonotonicTimeNanos(); return values; }
--- a/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/HostCpuBackend.java Fri Jan 20 10:48:09 2017 -0500 +++ b/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/HostCpuBackend.java Mon Jan 23 10:11:31 2017 -0500 @@ -38,8 +38,8 @@ import java.util.concurrent.ScheduledExecutorService; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.SysConf; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.SysConf; import com.redhat.thermostat.backend.HostPollingAction; import com.redhat.thermostat.backend.HostPollingBackend; import com.redhat.thermostat.common.Clock;
--- a/host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -49,7 +49,7 @@ import org.junit.Test; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.common.Clock; import com.redhat.thermostat.common.SystemClock; import com.redhat.thermostat.host.cpu.common.model.CpuStat;
--- a/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/HostMemoryBackend.java Fri Jan 20 10:48:09 2017 -0500 +++ b/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/HostMemoryBackend.java Mon Jan 23 10:11:31 2017 -0500 @@ -38,7 +38,7 @@ import java.util.concurrent.ScheduledExecutorService; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.backend.HostPollingAction; import com.redhat.thermostat.backend.HostPollingBackend; import com.redhat.thermostat.common.Version;
--- a/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilder.java Fri Jan 20 10:48:09 2017 -0500 +++ b/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilder.java Mon Jan 23 10:11:31 2017 -0500 @@ -41,10 +41,10 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.common.NotImplementedException; import com.redhat.thermostat.common.Size; +import com.redhat.thermostat.common.portability.PortableMemoryStat; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.host.memory.common.model.MemoryStat; import com.redhat.thermostat.shared.config.OS; @@ -130,7 +130,7 @@ private MemoryStat buildFromWindows() { long timestamp = System.currentTimeMillis(); - WindowsHelperImpl.MemoryStat memstat = new WindowsHelperImpl.MemoryStat(); + PortableMemoryStat memstat = PortableMemoryStat.build(); String wId = writerId.getWriterID(); return new MemoryStat(wId, timestamp, memstat.getTotal(), memstat.getFree(), memstat.getBuffers(), memstat.getCached(), memstat.getSwapTotal(), memstat.getSwapFree(), memstat.getCommitLimit());
--- a/host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -49,7 +49,7 @@ import org.junit.Before; import org.junit.Test; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.host.memory.common.model.MemoryStat; import com.redhat.thermostat.storage.core.WriterID;
--- a/numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/NumaWindowsCollectorImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ b/numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/NumaWindowsCollectorImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -1,57 +1,57 @@ -/* - * 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 - * <http://www.gnu.org/licenses/>. - * - * 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.numa.agent.internal; - -import com.redhat.thermostat.numa.common.NumaNodeStat; - -import java.io.IOException; - -public class NumaWindowsCollectorImpl implements NumaCollector { - - @Override - public NumaNodeStat[] collectData() throws IOException { - final NumaNodeStat[] nsa = new NumaNodeStat[1]; - final NumaNodeStat ns = new NumaNodeStat(); - nsa[0] = ns; - return nsa; - } - - @Override - public int getNumberOfNumaNodes() { - return 1; - } -} +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.numa.agent.internal; + +import com.redhat.thermostat.numa.common.NumaNodeStat; + +import java.io.IOException; + +public class NumaWindowsCollectorImpl implements NumaCollector { + + @Override + public NumaNodeStat[] collectData() throws IOException { + final NumaNodeStat[] nsa = new NumaNodeStat[1]; + final NumaNodeStat ns = new NumaNodeStat(); + nsa[0] = ns; + return nsa; + } + + @Override + public int getNumberOfNumaNodes() { + return 1; + } +}
--- a/process-handler/pom.xml Fri Jan 20 10:48:09 2017 -0500 +++ b/process-handler/pom.xml Mon Jan 23 10:11:31 2017 -0500 @@ -92,6 +92,12 @@ <artifactId>thermostat-common-core</artifactId> <version>${project.version}</version> </dependency> + + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-portability</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> </project>
--- a/process-handler/src/main/java/com/redhat/thermostat/service/internal/ProcessUtilitiesBase.java Fri Jan 20 10:48:09 2017 -0500 +++ b/process-handler/src/main/java/com/redhat/thermostat/service/internal/ProcessUtilitiesBase.java Mon Jan 23 10:11:31 2017 -0500 @@ -95,7 +95,7 @@ try { rt.exec(command); } catch (IOException e) { - logger.log(Level.WARNING, "can't run kill!", e); + logger.log(Level.WARNING, "can't run '" + command + "'", e); } }
--- a/process-handler/src/main/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilities.java Fri Jan 20 10:48:09 2017 -0500 +++ b/process-handler/src/main/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilities.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,6 +36,7 @@ package com.redhat.thermostat.service.internal.windows; +import com.redhat.thermostat.common.portability.PortableProcessImpl; import com.redhat.thermostat.service.internal.ProcessUtilitiesBase; import com.redhat.thermostat.service.process.UNIXSignal; @@ -73,8 +74,7 @@ @Override public void sendSignal(Integer pid, UNIXSignal signal) { - // TODO - port to Windows - exec("kill -s " + signal.signalName() + " " + pid); + PortableProcessImpl.INSTANCE.terminateProcess(pid); } }
--- a/process-handler/src/test/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilitiesTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/process-handler/src/test/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilitiesTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -86,24 +86,6 @@ } @Test - public void sendKillSignalTest() { - - process.sendSignal(12345, UNIXSignal.KILL); - - Assert.assertTrue(processArguments.contains("kill -s kill 12345")); - Assert.assertEquals(1, processArguments.size()); - } - - @Test - public void sendTermSignalTest() { - - process.sendSignal(12345, UNIXSignal.TERM); - - Assert.assertTrue(processArguments.contains("kill -s term 12345")); - Assert.assertEquals(1, processArguments.size()); - } - - @Test public void getProcessName() { String result = process.getProcessName(12345);
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListener.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListener.java Mon Jan 23 10:11:31 2017 -0500 @@ -44,9 +44,9 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder; import sun.jvmstat.monitor.MonitorException; import sun.jvmstat.monitor.MonitoredHost; import sun.jvmstat.monitor.MonitoredVm;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java Mon Jan 23 10:11:31 2017 -0500 @@ -42,15 +42,15 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder; import sun.jvmstat.monitor.HostIdentifier; import sun.jvmstat.monitor.MonitorException; import sun.jvmstat.monitor.MonitoredHost; import com.redhat.thermostat.agent.VmBlacklist; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; +import com.redhat.thermostat.common.portability.UserNameUtil; import com.redhat.thermostat.backend.BaseBackend; import com.redhat.thermostat.common.Version; import com.redhat.thermostat.common.utils.LoggingUtils;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackendActivator.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackendActivator.java Mon Jan 23 10:11:31 2017 -0500 @@ -41,7 +41,7 @@ import org.osgi.framework.ServiceRegistration; import com.redhat.thermostat.agent.VmBlacklist; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; +import com.redhat.thermostat.common.portability.UserNameUtil; import com.redhat.thermostat.backend.Backend; import com.redhat.thermostat.backend.BackendService; import com.redhat.thermostat.common.MultipleServiceTracker;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -43,8 +43,8 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.hostname.HostName; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.HostName; import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; import com.redhat.thermostat.common.Size; import com.redhat.thermostat.common.Size.Unit;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/LinuxInfoBuilderFactory.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/LinuxInfoBuilderFactory.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,12 +36,14 @@ package com.redhat.thermostat.backend.system.internal.linux; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; + +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.UserNameUtil; import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder; import com.redhat.thermostat.storage.core.WriterID; /** @@ -68,6 +70,6 @@ } public ProcessUserInfoBuilder createProcessUserInfoBuilder(final UserNameUtil userNameUtil) { - return new ProcessUserInfoBuilderImpl(dataSource, userNameUtil); + return ProcessUserInfo.createBuilder(dataSource, userNameUtil); } }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -46,7 +46,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; import com.redhat.thermostat.common.utils.LoggingUtils;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessUserInfoBuilderImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.backend.system.internal.linux; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.username.UserNameLookupException; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder; -import com.redhat.thermostat.common.utils.LoggingUtils; - -class ProcessUserInfoBuilderImpl implements ProcessUserInfoBuilder { - - private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo(); - private static final String PROC_STATUS_UID = "Uid:"; - private static final Logger logger = LoggingUtils.getLogger(ProcessUserInfoBuilderImpl.class); - private ProcDataSource source; - private UserNameUtil userNameUtil; - - ProcessUserInfoBuilderImpl(ProcDataSource source, UserNameUtil userNameUtil) { - this.source = source; - this.userNameUtil = userNameUtil; - } - - public ProcessUserInfo build(int pid) { - ProcessUserInfo info = NON_EXISTENT_USER; - try { - Reader reader = source.getStatusReader(pid); - long uid = getUidFromProcfs(new BufferedReader(reader)); - String name = null; - try { - name = userNameUtil.getUserName(uid); - } catch (UserNameLookupException e) { - logger.log(Level.WARNING, "Unable to retrieve username for uid: " + uid, e); - } - info = new ProcessUserInfo(uid, name); - } catch (IOException e) { - logger.log(Level.WARNING, "Unable to read user info for " + pid, e); - } - - return info; - } - - /* - * Look for the following line: - * Uid: <RealUid> <EffectiveUid> <SavedUid> <FSUid> - */ - private long getUidFromProcfs(BufferedReader br) throws IOException { - long uid = -1; - String line; - while ((line = br.readLine()) != null) { - line = line.trim(); - if (line.startsWith(PROC_STATUS_UID)) { - String[] parts = line.split("\\s+"); - if (parts.length == 5) { - try { - // Use Real UID - uid = Long.parseLong(parts[1]); - } catch (NumberFormatException e) { - throw new IOException("Unexpected output from ps command", e); - } - } - else { - throw new IOException("Expected 5 parts from split /proc/${pid}/status output, got " + parts.length); - } - } - } - if (uid < 0) { - throw new IOException("Unable to determine UID from /proc/${pid}/status"); - } - return uid; - } - - -} -
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/InfoBuilderFactory.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/InfoBuilderFactory.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,7 +36,8 @@ package com.redhat.thermostat.backend.system.internal.models; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; +import com.redhat.thermostat.common.portability.UserNameUtil; import com.redhat.thermostat.backend.system.internal.linux.LinuxInfoBuilderFactory; import com.redhat.thermostat.backend.system.internal.windows.WindowsInfoBuilderFactory; import com.redhat.thermostat.shared.config.OS;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/ProcessUserInfo.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.backend.system.internal.models; - -/** - * Information about a system process (in Thermostat, these are JVM processes) - */ -public class ProcessUserInfo { - - private long uid; - private String username; - - public ProcessUserInfo(long uid, String username) { - this.uid = uid; - this.username = username; - } - - public ProcessUserInfo() { - this.uid = -1; - this.username = null; - } - - public long getUid() { - return uid; - } - - public String getUsername() { - return username; - } -} \ No newline at end of file
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/ProcessUserInfoBuilder.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.backend.system.internal.models; - -/** - * Interface for ProcessUserInfo builders - */ -public interface ProcessUserInfoBuilder { - ProcessUserInfo build(int pid); -}
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,8 +36,9 @@ package com.redhat.thermostat.backend.system.internal.windows; -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; +import com.redhat.thermostat.common.portability.PortableHost; import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; +import com.redhat.thermostat.common.portability.PortableHostImpl; import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.storage.model.HostInfo; @@ -47,26 +48,26 @@ class WindowsHostInfoBuilderImpl implements HostInfoBuilder { private final WriterID writerID; - private final WindowsHelperImpl winHelper; + private final PortableHost helper; WindowsHostInfoBuilderImpl(final WriterID writerID) { - this(writerID, WindowsHelperImpl.INSTANCE); + this(writerID, PortableHostImpl.INSTANCE); } - WindowsHostInfoBuilderImpl(final WriterID writerID, WindowsHelperImpl winHelper) { + WindowsHostInfoBuilderImpl(final WriterID writerID, PortableHost helper) { this.writerID = writerID; - this.winHelper = winHelper; + this.helper = helper; } @Override public HostInfo build() { String wId = writerID.getWriterID(); return new HostInfo(wId, - winHelper.getHostName(), - winHelper.getOSName(), - winHelper.getOSVersion(), - winHelper.getCPUModel(), - winHelper.getCPUCount(), - winHelper.getTotalMemory()); + helper.getHostName(), + helper.getOSName(), + helper.getOSVersion(), + helper.getCPUModel(), + helper.getCPUCount(), + helper.getTotalMemory()); } }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactory.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactory.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,11 +36,12 @@ package com.redhat.thermostat.backend.system.internal.windows; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; +import com.redhat.thermostat.common.portability.UserNameUtil; import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder; import com.redhat.thermostat.storage.core.WriterID; /** @@ -60,6 +61,6 @@ } public ProcessUserInfoBuilder createProcessUserInfoBuilder(final UserNameUtil userNameUtil) { - return new WindowsUserInfoBuilderImpl(); + return ProcessUserInfo.createBuilder(null, userNameUtil); } }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,8 +36,9 @@ package com.redhat.thermostat.backend.system.internal.windows; -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessImpl; import java.util.Map; @@ -46,18 +47,18 @@ */ class WindowsProcessEnvironmentBuilderImpl implements ProcessEnvironmentBuilder { - private final WindowsHelperImpl winHelper; + private final PortableProcess helper; WindowsProcessEnvironmentBuilderImpl() { - this(WindowsHelperImpl.INSTANCE); + this(PortableProcessImpl.INSTANCE); } - WindowsProcessEnvironmentBuilderImpl(WindowsHelperImpl wh) { - winHelper = wh; + WindowsProcessEnvironmentBuilderImpl(PortableProcess wh) { + helper = wh; } @Override public Map<String, String> build(int pid) { - return winHelper.getEnvironment(pid); + return helper.getEnvironment(pid); } }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsUserInfoBuilderImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.backend.system.internal.windows; - -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder; -import com.redhat.thermostat.common.utils.LoggingUtils; - -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Build User information via Windows helper classes - */ -class WindowsUserInfoBuilderImpl implements ProcessUserInfoBuilder { - - private final WindowsHelperImpl winHelper; - private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo(); - private static final Logger logger = LoggingUtils.getLogger(WindowsUserInfoBuilderImpl.class); - - WindowsUserInfoBuilderImpl() { - this(WindowsHelperImpl.INSTANCE); - } - - WindowsUserInfoBuilderImpl(WindowsHelperImpl winHelper) { - this.winHelper = winHelper; - } - - @Override - public ProcessUserInfo build(int pid) { - ProcessUserInfo info = NON_EXISTENT_USER; - try { - final long uid = winHelper.getUid(pid); - final String name = winHelper.getUserName(pid); - info = new ProcessUserInfo(uid, name); - } catch (Exception e) { - logger.log(Level.WARNING, "Unable to read user info for " + pid, e); - } - - return info; - } -}
--- a/system-backend/src/main/native/WindowsHelperImpl.c Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright 2012-2014 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 - * <http://www.gnu.org/licenses/>. - * - * 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. - */ - -#include "com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl.h" -#include <jni.h> -#include <unistd.h> -#include <string.h> - -#if !defined(_WIN32) -# include <netdb.h> -#else // windows -# include <winsock2.h> -#endif - -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif /* NI_MAXHOST */ - -/* - * Class: com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl - * Method: getHostName0 - * Signature: ()Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl_getHostName0 - (JNIEnv *env, jclass winHelperClass) -{ - char hostname[NI_MAXHOST]; - memset(hostname, 0, sizeof(hostname)); - - if (gethostname(hostname, sizeof(hostname)) == 0) { - return (*env)->NewStringUTF(env, hostname); - } - return NULL; -} - -/* - * Class: com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl - * Method: getUid0 - * Signature: (I)I - */ -JNIEXPORT jint JNICALL -Java_com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl_getUid0 - (JNIEnv *env, jclass winHelperClass, jint pid) -{ - // TODO - implement this stub - return 987654321; -} - -/* - * Class: com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl - * Method: getUserName0 - * Signature: (I)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl_getUserName0 - (JNIEnv *env, jclass winHelperClass, jint pid) -{ - // TODO - implement this stub - return (*env)->NewStringUTF(env, "(stub username)"); -} - -/* - * Class: com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl - * Method: getEnvironment0 - * Signature: ()[Ljava/lang/String; - */ -JNIEXPORT jobjectArray JNICALL -Java_com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl_getEnvironment0 - (JNIEnv *env, jclass winHelperClass, jint pid) -{ - // TODO - implement this stub - return NULL; -}
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListenerTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListenerTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -56,14 +56,14 @@ import java.util.Set; import java.util.UUID; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import com.redhat.thermostat.agent.VmBlacklist; import com.redhat.thermostat.agent.VmStatusListener.Status; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo; import com.redhat.thermostat.storage.core.HostRef; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.core.WriterID;
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/SystemBackendTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/SystemBackendTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -48,7 +48,7 @@ import org.junit.Test; import com.redhat.thermostat.agent.VmBlacklist; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; +import com.redhat.thermostat.common.portability.UserNameUtil; import com.redhat.thermostat.common.Version; import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.storage.dao.HostInfoDAO;
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -51,7 +51,7 @@ import org.junit.Before; import org.junit.Test; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.backend.system.internal.linux.HostInfoBuilderImpl.HostCpuInfo; import com.redhat.thermostat.backend.system.internal.linux.HostInfoBuilderImpl.HostMemoryInfo; import com.redhat.thermostat.backend.system.internal.linux.HostInfoBuilderImpl.HostOsInfo;
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -57,7 +57,7 @@ import org.junit.Assume; import org.junit.Test; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.testutils.TestUtils; public class ProcessEnvironmentBuilderTest {
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessUserInfoBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.backend.system.internal.linux; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.io.StringReader; - -import org.junit.Test; - -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.username.UserNameLookupException; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo; -import com.redhat.thermostat.common.tools.ApplicationException; - -public class ProcessUserInfoBuilderTest { - - @Test - public void testBuild() throws UserNameLookupException, IOException, ApplicationException { - StringReader reader = new StringReader("Uid: 2000 2000 2000 2000"); - ProcDataSource source = mock(ProcDataSource.class); - UserNameUtil util = mock(UserNameUtil.class); - when(util.getUserName(2000)).thenReturn("myUser"); - when(source.getStatusReader(anyInt())).thenReturn(reader); - ProcessUserInfoBuilderImpl builder = new ProcessUserInfoBuilderImpl(source, util); - ProcessUserInfo info = builder.build(0); - - assertEquals(2000, info.getUid()); - assertEquals("myUser", info.getUsername()); - } - - @Test - public void testBuildErrorUid() throws IOException, ApplicationException { - StringReader reader = new StringReader(""); - ProcDataSource source = mock(ProcDataSource.class); - UserNameUtil util = mock(UserNameUtil.class); - when(source.getStatusReader(anyInt())).thenReturn(reader); - ProcessUserInfoBuilderImpl builder = new ProcessUserInfoBuilderImpl(source, util); - ProcessUserInfo info = builder.build(0); - - assertEquals(-1, info.getUid()); - assertEquals(null, info.getUsername()); - } - - @Test - public void testBuildErrorUsername() throws IOException, UserNameLookupException, ApplicationException { - StringReader reader = new StringReader("Uid: 2000 2000 2000 2000"); - ProcDataSource source = mock(ProcDataSource.class); - UserNameUtil util = mock(UserNameUtil.class); - when(util.getUserName(2000)).thenReturn(null); - when(source.getStatusReader(anyInt())).thenReturn(reader); - ProcessUserInfoBuilderImpl builder = new ProcessUserInfoBuilderImpl(source, util); - ProcessUserInfo info = builder.build(0); - - assertEquals(2000, info.getUid()); - assertEquals(null, info.getUsername()); - } - -} -
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,7 +36,7 @@ package com.redhat.thermostat.backend.system.internal.windows; -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; +import com.redhat.thermostat.common.portability.PortableHost; import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; import com.redhat.thermostat.shared.config.OS; import com.redhat.thermostat.storage.core.WriterID; @@ -54,18 +54,18 @@ public class WindowsHostInfoBuilderTest { private WriterID writerId; - private WindowsHelperImpl whelp; + private PortableHost helper; @Before public void setup() { writerId = mock(WriterID.class); - whelp = mock(WindowsHelperImpl.class); - when(whelp.getHostName()).thenReturn("testhost"); - when(whelp.getOSName()).thenReturn("testos"); - when(whelp.getOSVersion()).thenReturn("testversion"); - when(whelp.getCPUModel()).thenReturn("testcpu"); - when(whelp.getCPUCount()).thenReturn(4567); - when(whelp.getTotalMemory()).thenReturn(9876L); + helper = mock(PortableHost.class); + when(helper.getHostName()).thenReturn("testhost"); + when(helper.getOSName()).thenReturn("testos"); + when(helper.getOSVersion()).thenReturn("testversion"); + when(helper.getCPUModel()).thenReturn("testcpu"); + when(helper.getCPUCount()).thenReturn(4567); + when(helper.getTotalMemory()).thenReturn(9876L); } // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path @@ -79,7 +79,7 @@ @Test public void testGetInfo() { - final HostInfoBuilder ib = new WindowsHostInfoBuilderImpl(writerId, whelp); + final HostInfoBuilder ib = new WindowsHostInfoBuilderImpl(writerId, helper); final HostInfo hi = ib.build(); assertEquals("testhost",hi.getHostname()); assertEquals("testos", hi.getOsName());
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactoryTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactoryTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -39,7 +39,6 @@ import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder; import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory; import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder; import org.junit.Test; import static org.junit.Assert.assertNotNull; @@ -62,12 +61,4 @@ assertNotNull(hib); assertTrue(hib instanceof WindowsProcessEnvironmentBuilderImpl); } - - @Test - public void testCreateProcessUserInfoBuilder() { - final InfoBuilderFactory builder = new WindowsInfoBuilderFactory(); - final ProcessUserInfoBuilder hib = builder.createProcessUserInfoBuilder(null); - assertNotNull(hib); - assertTrue(hib instanceof WindowsUserInfoBuilderImpl); - } }
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,7 +36,7 @@ package com.redhat.thermostat.backend.system.internal.windows; -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; +import com.redhat.thermostat.common.portability.PortableProcess; import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder; import com.redhat.thermostat.shared.config.OS; @@ -62,7 +62,7 @@ */ public class WindowsProcessEnvironmentBuilderTest { - private WindowsHelperImpl whelp; + private PortableProcess whelp; private static final int FAKE_PID = 4567; private static final String PATH_KEY = "PATH"; @@ -72,7 +72,7 @@ @Before public void setup() { - whelp = mock(WindowsHelperImpl.class); + whelp = mock(PortableProcess.class); goodMap.put(PATH_KEY, FAKE_PATH); when(whelp.getEnvironment(anyInt())).thenReturn(null); when(whelp.getEnvironment(eq(FAKE_PID))).thenReturn(goodMap);
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessUserInfoBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ /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 - * <http://www.gnu.org/licenses/>. - * - * 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.backend.system.internal.windows; - -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo; -import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder; -import com.redhat.thermostat.shared.config.OS; - -import org.junit.Assume; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * test windows user info builder - */ -public class WindowsProcessUserInfoBuilderTest { - - private WindowsHelperImpl whelp; - - private static final String FAKE_USERNAME = "testuser"; - private static final int FAKE_PID = 4567; - private static final int FAKE_UID = 7652; - - @Before - public void setup() { - whelp = mock(WindowsHelperImpl.class); - when(whelp.getUserName(anyInt())).thenReturn("badname"); - when(whelp.getUserName(eq(FAKE_PID))).thenReturn(FAKE_USERNAME); - when(whelp.getUid(anyInt())).thenReturn(11); - when(whelp.getUid(eq(FAKE_PID))).thenReturn(FAKE_UID); - } - - // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path - @Test - @Ignore - public void testSimpleBuild() { - Assume.assumeTrue(OS.IS_WINDOWS); - ProcessUserInfo info = new WindowsUserInfoBuilderImpl().build(FAKE_PID); - assertNotNull(info); - } - - @Test - public void testGetInfoFromGoodPid() { - final ProcessUserInfoBuilder ib = new WindowsUserInfoBuilderImpl(whelp); - final ProcessUserInfo hi = ib.build(FAKE_PID); - assertEquals(FAKE_USERNAME, hi.getUsername()); - assertEquals(FAKE_UID, hi.getUid()); - } - - @Test - public void testGetInfoFromBadPid() { - final ProcessUserInfoBuilder ib = new WindowsUserInfoBuilderImpl(whelp); - final ProcessUserInfo hi = ib.build(FAKE_PID+1); - assertNotSame(FAKE_USERNAME,hi.getUsername()); - assertNotSame(FAKE_UID, hi.getUid()); - } -}
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java Mon Jan 23 10:11:31 2017 -0500 @@ -49,12 +49,13 @@ import org.jboss.byteman.agent.submit.Submit; +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.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.ProcessUserInfoBuilder.ProcessUserInfo; import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus; @@ -90,8 +91,8 @@ } // for testing only - BytemanAgentAttachManager(BytemanAttacher attacher, IPCEndpointsManager ipcManager, VmBytemanDAO vmBytemanDao, SubmitHelper submit, - WriterID writerId, ProcessUserInfoBuilder userInfoBuilder, FileSystemUtils fsUtils) { + BytemanAgentAttachManager(BytemanAttacher attacher, IPCEndpointsManager ipcManager, VmBytemanDAO vmBytemanDao, SubmitHelper submit, + WriterID writerId, ProcessUserInfoBuilder userInfoBuilder, FileSystemUtils fsUtils) { this.attacher = attacher; this.ipcManager = ipcManager; this.vmBytemanDao = vmBytemanDao;
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java Mon Jan 23 10:11:31 2017 -0500 @@ -49,7 +49,7 @@ 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.portability.ProcessChecker; import com.redhat.thermostat.common.utils.LoggingUtils; import com.sun.tools.attach.AgentInitializationException; import com.sun.tools.attach.AgentLoadException;
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java Mon Jan 23 10:11:31 2017 -0500 @@ -44,6 +44,8 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.redhat.thermostat.common.portability.ProcessUserInfo; +import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Reference; @@ -53,8 +55,8 @@ import com.redhat.thermostat.agent.command.RequestReceiver; import com.redhat.thermostat.agent.ipc.server.AgentIPCService; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +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; @@ -154,7 +156,7 @@ } protected void bindUserNameUtil(UserNameUtil userNameUtil) { - ProcessUserInfoBuilder userInfoBuilder = new ProcessUserInfoBuilder(new ProcDataSource(), userNameUtil); + ProcessUserInfoBuilder userInfoBuilder = ProcessUserInfo.createBuilder(new ProcDataSource(), userNameUtil); attachManager.setUserInfoBuilder(userInfoBuilder); }
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/ProcessUserInfoBuilder.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.username.UserNameLookupException; -import com.redhat.thermostat.agent.utils.username.UserNameUtil; -import com.redhat.thermostat.common.utils.LoggingUtils; - -/* - * FIXME: This class was copied from system-backend. - * Replace when this information is available from an API. - */ -class ProcessUserInfoBuilder { - - private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo(); - private static final String PROC_STATUS_UID = "Uid:"; - private static final Logger logger = LoggingUtils.getLogger(ProcessUserInfoBuilder.class); - private ProcDataSource source; - private UserNameUtil userNameUtil; - - ProcessUserInfoBuilder(ProcDataSource source, UserNameUtil userNameUtil) { - this.source = source; - this.userNameUtil = userNameUtil; - } - - static class ProcessUserInfo { - - private long uid; - private String username; - - ProcessUserInfo(long uid, String username) { - this.uid = uid; - this.username = username; - } - - ProcessUserInfo() { - this.uid = -1; - this.username = null; - } - - public long getUid() { - return uid; - } - - public String getUsername() { - return username; - } - } - - ProcessUserInfo build(int pid) { - ProcessUserInfo info = NON_EXISTENT_USER; - try { - Reader reader = source.getStatusReader(pid); - long uid = getUidFromProcfs(new BufferedReader(reader)); - String name = null; - try { - name = userNameUtil.getUserName(uid); - } catch (UserNameLookupException e) { - logger.log(Level.WARNING, "Unable to retrieve username for uid: " + uid, e); - } - info = new ProcessUserInfo(uid, name); - } catch (IOException e) { - logger.log(Level.WARNING, "Unable to read user info for " + pid, e); - } - - return info; - } - - /* - * Look for the following line: - * Uid: <RealUid> <EffectiveUid> <SavedUid> <FSUid> - */ - private long getUidFromProcfs(BufferedReader br) throws IOException { - long uid = -1; - String line; - while ((line = br.readLine()) != null) { - line = line.trim(); - if (line.startsWith(PROC_STATUS_UID)) { - String[] parts = line.split("\\s+"); - if (parts.length == 5) { - try { - // Use Real UID - uid = Long.parseLong(parts[1]); - } catch (NumberFormatException e) { - throw new IOException("Unexpected output from ps command", e); - } - } - else { - throw new IOException("Expected 5 parts from split /proc/${pid}/status output, got " + parts.length); - } - } - } - if (uid < 0) { - throw new IOException("Unable to determine UID from /proc/${pid}/status"); - } - return uid; - } - - -} -
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -63,13 +63,14 @@ 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.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.storage.core.WriterID; 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.agent.internal.ProcessUserInfoBuilder.ProcessUserInfo; import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO; import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -56,7 +56,7 @@ import org.mockito.ArgumentCaptor; import com.redhat.thermostat.agent.ipc.server.AgentIPCService; -import com.redhat.thermostat.agent.utils.ProcessChecker; +import com.redhat.thermostat.common.portability.ProcessChecker; import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.BtmInstallHelper; import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.InstallResult;
--- a/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,7 +36,7 @@ package com.redhat.thermostat.vm.cpu.agent.internal; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.common.utils.LoggingUtils; import java.io.BufferedReader;
--- a/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuBackend.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuBackend.java Mon Jan 23 10:11:31 2017 -0500 @@ -43,14 +43,14 @@ import java.util.logging.Logger; import com.redhat.thermostat.agent.VmStatusListenerRegistrar; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; -import com.redhat.thermostat.agent.utils.SysConf; -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.SysConf; import com.redhat.thermostat.backend.VmPollingAction; import com.redhat.thermostat.backend.VmPollingBackend; import com.redhat.thermostat.common.Clock; import com.redhat.thermostat.common.SystemClock; import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.common.portability.PortableHostImpl; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.shared.config.OS; import com.redhat.thermostat.storage.core.WriterID; @@ -114,7 +114,7 @@ } private int getWindowsCpuCount() { - return WindowsHelperImpl.INSTANCE.getCPUCount(); + return PortableHostImpl.INSTANCE.getCPUCount(); } private int getLinuxCpuCount(ProcDataSource dataSource) {
--- a/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/WindowsProcessStatusInfoBuilderImpl.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/WindowsProcessStatusInfoBuilderImpl.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,29 +36,22 @@ package com.redhat.thermostat.vm.cpu.agent.internal; -import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl; -import com.redhat.thermostat.common.utils.LoggingUtils; - -import java.util.logging.Logger; +import com.redhat.thermostat.common.portability.PortableProcessImpl; +import com.redhat.thermostat.common.portability.PortableProcessStat; /** * Extract status information about the process */ public class WindowsProcessStatusInfoBuilderImpl implements ProcessStatusInfoBuilder { - //private static final Logger logger = LoggingUtils.getLogger(WindowsProcessStatusInfoBuilderImpl.class); - WindowsProcessStatusInfoBuilderImpl() { } public ProcessStatusInfo build(int pid) { - final long[] info = WindowsHelperImpl.INSTANCE.getProcessCPUInfo(pid); + final PortableProcessStat info = PortableProcessImpl.INSTANCE.getProcessStat(pid); - final long utime = info[1]; - final long stime = info[2]; - - return new ProcessStatusInfo(pid, utime, stime); + return new ProcessStatusInfo(pid, info.getUserTime(), info.getKernelTime()); } }
--- a/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -48,7 +48,7 @@ import org.junit.Test; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; public class LinuxProcessStatusInfoBuilderTest {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilder.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,65 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.io.agent.internal; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.io.common.VmIoStat; + +public class LinuxVmIoStatBuilder implements VmIoStatBuilder { + + private final Clock clock; + private final ProcIoDataReader ioReader; + private final String writerId; + + LinuxVmIoStatBuilder(Clock clock, ProcIoDataReader ioReader, WriterID writerId) { + this.clock = clock; + this.ioReader = ioReader; + + this.writerId = writerId.getWriterID(); + } + + public synchronized VmIoStat build(String vmId, Integer pid) { + ProcIoData data = ioReader.read(pid); + if (data == null) { + return null; + } + long miliTime = clock.getRealTimeMillis(); + return new VmIoStat(writerId, vmId, miliTime, data.rchar, data.wchar, data.syscr, data.syscw); + } + +}
--- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReader.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReader.java Mon Jan 23 10:11:31 2017 -0500 @@ -41,7 +41,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.common.utils.LoggingUtils; /**
--- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackend.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackend.java Mon Jan 23 10:11:31 2017 -0500 @@ -37,12 +37,13 @@ package com.redhat.thermostat.vm.io.agent.internal; import com.redhat.thermostat.agent.VmStatusListenerRegistrar; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.backend.VmListenerBackend; import com.redhat.thermostat.backend.VmUpdate; import com.redhat.thermostat.backend.VmUpdateListener; import com.redhat.thermostat.common.Clock; import com.redhat.thermostat.common.Version; +import com.redhat.thermostat.shared.config.OS; import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.vm.io.common.Constants; import com.redhat.thermostat.vm.io.common.VmIoStat; @@ -58,7 +59,8 @@ VmStatusListenerRegistrar registrar, WriterID writerId) { this(version, vmIoStatDao, - new VmIoStatBuilder(clock, new ProcIoDataReader(new ProcDataSource()), writerId), + OS.IS_LINUX ? new LinuxVmIoStatBuilder(clock, new ProcIoDataReader(new ProcDataSource()), writerId) + : new WindowsVmIoStatBuilder(clock, writerId), registrar, writerId); }
--- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilder.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilder.java Mon Jan 23 10:11:31 2017 -0500 @@ -36,30 +36,8 @@ package com.redhat.thermostat.vm.io.agent.internal; -import com.redhat.thermostat.common.Clock; -import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.vm.io.common.VmIoStat; -public class VmIoStatBuilder { - - private final Clock clock; - private final ProcIoDataReader ioReader; - private final String writerId; - - public VmIoStatBuilder(Clock clock, ProcIoDataReader ioReader, WriterID writerId) { - this.clock = clock; - this.ioReader = ioReader; - - this.writerId = writerId.getWriterID(); - } - - public synchronized VmIoStat build(String vmId, Integer pid) { - ProcIoData data = ioReader.read(pid); - if (data == null) { - return null; - } - long miliTime = clock.getRealTimeMillis(); - return new VmIoStat(writerId, vmId, miliTime, data.rchar, data.wchar, data.syscr, data.syscw); - } - +public interface VmIoStatBuilder { + VmIoStat build(String vmId, Integer pid); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilder.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,60 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.io.agent.internal; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.common.portability.PortableVmIoStat; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.io.common.VmIoStat; + +public class WindowsVmIoStatBuilder implements VmIoStatBuilder { + + private final Clock clock; + private final String writerId; + + WindowsVmIoStatBuilder(Clock clock, WriterID writerId) { + this.clock = clock; + this.writerId = writerId.getWriterID(); + } + + public synchronized VmIoStat build(String vmId, Integer pid) { + + PortableVmIoStat data = PortableVmIoStat.build(clock, pid); + return new VmIoStat(writerId, vmId, data.getTimeStamp(), data.getCharactersRead(), data.getCharactersWritten(), data.getReadSyscalls(), data.getWriteSyscalls()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,100 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.io.agent.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.io.common.VmIoStat; + +public class LinuxVmIoStatBuilderTest { + + private WriterID writerID; + + @Before + public void setup() { + writerID = mock(WriterID.class); + } + + @Test + public void testBuilderBuildsNullForUnknownPid() { + Clock clock = mock(Clock.class); + ProcIoDataReader procDataReader = mock(ProcIoDataReader.class); + LinuxVmIoStatBuilder builder = new LinuxVmIoStatBuilder(clock, procDataReader, writerID); + VmIoStat result = builder.build("vmId", 0); + assertNull(result); + } + + @Test + public void testBuildWithSufficientInformation() { + final int PID = 0; + + int rchar = 1; + int wchar = 2; + int syscr = 3; + int syscw = 4; + int read_bytes = 5; + int write_bytes = 6; + int cancelled_write_bytes = 7; + + final ProcIoData data = new ProcIoData(rchar, wchar, syscr, syscw, + read_bytes, write_bytes, cancelled_write_bytes); + + ProcIoDataReader ioReader = mock(ProcIoDataReader.class); + when(ioReader.read(PID)).thenReturn(data); + Clock clock = mock(Clock.class); + + LinuxVmIoStatBuilder builder = new LinuxVmIoStatBuilder(clock, ioReader, writerID); + + VmIoStat ioData = builder.build("vmId", PID); + assertNotNull(ioData); + assertEquals(rchar, ioData.getCharactersRead()); + assertEquals(wchar, ioData.getCharactersWritten()); + assertEquals(syscr, ioData.getReadSyscalls()); + assertEquals(syscw, ioData.getWriteSyscalls()); + } + +} +
--- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReaderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReaderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -44,7 +44,7 @@ import org.junit.Test; -import com.redhat.thermostat.agent.utils.linux.ProcDataSource; +import com.redhat.thermostat.common.portability.linux.ProcDataSource; public class ProcIoDataReaderTest {
--- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackendTest.java Fri Jan 20 10:48:09 2017 -0500 +++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackendTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -40,28 +40,18 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isA; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - +import com.redhat.thermostat.shared.config.OS; import org.junit.Before; import org.junit.Test; -import org.mockito.ArgumentCaptor; -import com.redhat.thermostat.agent.VmStatusListener.Status; import com.redhat.thermostat.agent.VmStatusListenerRegistrar; -import com.redhat.thermostat.common.Clock; import com.redhat.thermostat.common.Ordered; import com.redhat.thermostat.common.Version; import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.vm.io.common.VmIoStat; import com.redhat.thermostat.vm.io.common.VmIoStatDAO; public class VmIoBackendTest { @@ -81,7 +71,7 @@ registrar = mock(VmStatusListenerRegistrar.class); WriterID id = mock(WriterID.class); - ioStatBuilder = mock(VmIoStatBuilder.class); + ioStatBuilder = OS.IS_LINUX ? mock(LinuxVmIoStatBuilder.class) : mock(WindowsVmIoStatBuilder.class); backend = new VmIoBackend(version, vmIoStatDao, ioStatBuilder, registrar, id); }
--- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilderTest.java Fri Jan 20 10:48:09 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +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 - * <http://www.gnu.org/licenses/>. - * - * 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.io.agent.internal; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.common.Clock; -import com.redhat.thermostat.storage.core.WriterID; -import com.redhat.thermostat.vm.io.common.VmIoStat; - -public class VmIoStatBuilderTest { - - private WriterID writerID; - - @Before - public void setup() { - writerID = mock(WriterID.class); - } - - @Test - public void testBuilderBuildsNullForUnknownPid() { - Clock clock = mock(Clock.class); - ProcIoDataReader procDataReader = mock(ProcIoDataReader.class); - VmIoStatBuilder builder = new VmIoStatBuilder(clock, procDataReader, writerID); - VmIoStat result = builder.build("vmId", 0); - assertNull(result); - } - - @Test - public void testBuildWithSufficientInformation() { - final int PID = 0; - - int rchar = 1; - int wchar = 2; - int syscr = 3; - int syscw = 4; - int read_bytes = 5; - int write_bytes = 6; - int cancelled_write_bytes = 7; - - final ProcIoData data = new ProcIoData(rchar, wchar, syscr, syscw, - read_bytes, write_bytes, cancelled_write_bytes); - - ProcIoDataReader ioReader = mock(ProcIoDataReader.class); - when(ioReader.read(PID)).thenReturn(data); - Clock clock = mock(Clock.class); - - VmIoStatBuilder builder = new VmIoStatBuilder(clock, ioReader, writerID); - - VmIoStat ioData = builder.build("vmId", PID); - assertNotNull(ioData); - assertEquals(rchar, ioData.getCharactersRead()); - assertEquals(wchar, ioData.getCharactersWritten()); - assertEquals(syscr, ioData.getReadSyscalls()); - assertEquals(syscw, ioData.getWriteSyscalls()); - } - -} -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilderTest.java Mon Jan 23 10:11:31 2017 -0500 @@ -0,0 +1,72 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.io.agent.internal; + +import com.redhat.thermostat.common.Clock; +import com.redhat.thermostat.shared.config.OS; +import com.redhat.thermostat.storage.core.WriterID; +import com.redhat.thermostat.vm.io.common.VmIoStat; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class WindowsVmIoStatBuilderTest { + + private WriterID writerID; + + @Before + public void setup() { + writerID = mock(WriterID.class); + } + + @Test + public void testBuilderBuildsNullForUnknownPid() { + Assume.assumeTrue(OS.IS_WINDOWS); + Clock clock = mock(Clock.class); + VmIoStatBuilder builder = new WindowsVmIoStatBuilder(clock, writerID); + VmIoStat result = builder.build("vmId", 0); + assertNull(result); + } + +} +