diff options
author | HÃ¥kon Hallingstad <hakon@oath.com> | 2018-01-29 10:31:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-29 10:31:46 +0100 |
commit | 4027310dcef4a098ff1b93c1d14bca4daf805522 (patch) | |
tree | e9d5d5bef04a5ab13b58903d6dadf8c1484330c9 | |
parent | 89e160f6924c41e182fad7af44a409bef8604440 (diff) | |
parent | 6d85bc7699c8ae9664efc62eb4905d4d86de5454 (diff) |
Merge pull request #4795 from vespa-engine/hakonhall/implement-debug-handler
Implement debug handler
21 files changed, 173 insertions, 11 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/TaskContext.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/TaskContext.java index 9def627e87f..87491367514 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/TaskContext.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/TaskContext.java @@ -18,4 +18,6 @@ public interface TaskContext { FileSystem fileSystem(); void logSystemModification(Logger logger, String actionDescription); + + default boolean executeSubtask(IdempotentTask task) { return false; } } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelper.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelper.java new file mode 100644 index 00000000000..dfcaba7c4bb --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelper.java @@ -0,0 +1,53 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +package com.yahoo.vespa.hosted.node.admin.provider; + +import javax.annotation.concurrent.ThreadSafe; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * Class to make it easier to implement a NodeAdminDebugHandler: + * - Forward to sub-NodeAdminDebugHandlers with addHandler, + * - Specify constants with addConstant + * - Forwarding to methods that dynamically build debug objects with addThreadSafeSupplier. + * + * @author hakonhall + */ +@ThreadSafe +public class DebugHandlerHelper implements NodeAdminDebugHandler { + private Object monitor = new Object(); + private final ConcurrentMap<String, Supplier<Object>> suppliers = new ConcurrentHashMap<>(); + + public void addThreadSafeSupplier(String name, Supplier<Object> threadSafeSupplier) { + Supplier<Object> previousSupplier = suppliers.putIfAbsent(name, threadSafeSupplier); + if (previousSupplier != null) { + throw new IllegalArgumentException(name + " is already registered"); + } + } + + public void addHandler(String name, NodeAdminDebugHandler handler) { + addThreadSafeSupplier(name, () -> handler.getDebugPage()); + } + + public void addConstant(String name, String value) { + addThreadSafeSupplier(name, () -> value); + } + + public void remove(String name) { + Supplier<Object> supplier = suppliers.remove(name); + if (supplier == null) { + throw new IllegalArgumentException(name + " is not registered"); + } + } + + @Override + public Map<String, Object> getDebugPage() { + return suppliers.entrySet().stream().collect(Collectors.toMap( + Map.Entry::getKey, + entry -> entry.getValue().get())); + } +} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminDebugHandler.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminDebugHandler.java new file mode 100644 index 00000000000..7b5eaa2f326 --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminDebugHandler.java @@ -0,0 +1,20 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +package com.yahoo.vespa.hosted.node.admin.provider; + +import javax.annotation.concurrent.ThreadSafe; +import java.util.Map; + +/** + * Interface for supporting debug info to introspect e.g. internal state. + * + * @author hakonhall + */ +@ThreadSafe +public interface NodeAdminDebugHandler { + /** + * The Object in the map values must be serializable with Jackson's ObjectMapper. + * May be called concurrently by different threads. + */ + Map<String, Object> getDebugPage(); +} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminStateUpdater.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminStateUpdater.java index 755e1301c12..841f464e014 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminStateUpdater.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminStateUpdater.java @@ -1,9 +1,10 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.node.admin.provider; -import java.util.Map; +import javax.annotation.concurrent.ThreadSafe; -public interface NodeAdminStateUpdater { +@ThreadSafe +public interface NodeAdminStateUpdater extends NodeAdminDebugHandler { enum State { TRANSITIONING, RESUMED, SUSPENDED_NODE_ADMIN, SUSPENDED} /** @@ -12,6 +13,4 @@ public interface NodeAdminStateUpdater { * has converged. */ boolean setResumeStateAndCheckIfResumed(State wantedState); - - Map<String, Object> getDebugPage(); } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileAttributes.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileAttributes.java index c99d5850909..3910398a040 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileAttributes.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileAttributes.java @@ -6,6 +6,11 @@ import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFilePermissions; import java.time.Instant; +/** + * This wrapper around PosixFileAttributes. + * + * @author hakonhall + */ public class FileAttributes { private final PosixFileAttributes attributes; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileContentCache.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileContentCache.java index ac50ff0cbab..ca79e8bb113 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileContentCache.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileContentCache.java @@ -7,6 +7,8 @@ import java.util.Optional; /** * Class to avoid repeated reads of file content when the file seldom changes. + * + * @author hakonhall */ class FileContentCache { private final UnixPath path; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileSync.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileSync.java index f103ab394ef..d8b8aadfff7 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileSync.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileSync.java @@ -16,6 +16,8 @@ import java.util.logging.Logger; * mutating file operations, e.g. setting file content, setting owner, etc. * * Only changes to the file is logged. + * + * @author hakohall */ // @ThreadUnsafe public class FileSync { diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileWriter.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileWriter.java index 2f22c94781f..58518ae5a15 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileWriter.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileWriter.java @@ -7,6 +7,11 @@ import org.glassfish.jersey.internal.util.Producer; import java.nio.file.Files; import java.nio.file.Path; +/** + * Write a file + * + * @author hakonhall + */ public class FileWriter { private final Path path; private final FileSync fileSync; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java index c36567e6135..9bcf601c262 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java @@ -6,6 +6,9 @@ import java.io.UncheckedIOException; import java.nio.file.NoSuchFileException; import java.util.Optional; +/** + * @author hakonhall + */ public class IOExceptionUtil { public static <T> void uncheck(RunnableThrowingIOException<T> runnable) { try { diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/PartialFileData.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/PartialFileData.java index d29c01179f2..b931a374230 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/PartialFileData.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/PartialFileData.java @@ -6,6 +6,8 @@ import java.util.Optional; /** * Represents a subset of a file's content, owner, group, and permissions. + * + * @author hakonhall */ // @Immutable public class PartialFileData { diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TemplateFile.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TemplateFile.java index 1d5b5f42cf3..e4dd5cf5d9c 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TemplateFile.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TemplateFile.java @@ -9,6 +9,11 @@ import org.apache.velocity.app.VelocityEngine; import java.io.StringWriter; import java.nio.file.Path; +/** + * Make a file based on a Velocity template file. + * + * @author hakonhall + */ public class TemplateFile { private final Path templatePath; private final VelocityEngine velocityEngine; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java index 05691bfcdc7..aaffea05d1e 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java @@ -19,6 +19,11 @@ import java.util.Set; import static com.yahoo.vespa.hosted.node.admin.task.util.file.IOExceptionUtil.uncheck; +/** + * Thin wrapper around java.nio.file.Path, especially nice for UNIX-specific features. + * + * @author hakonhall + */ // @Immutable public class UnixPath { private final Path path; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ChildProcess.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ChildProcess.java index 9c3333d41ae..00bcca71970 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ChildProcess.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ChildProcess.java @@ -3,6 +3,9 @@ package com.yahoo.vespa.hosted.node.admin.task.util.process; import java.nio.file.Path; +/** + * @author hakonhall + */ public interface ChildProcess extends AutoCloseable { ChildProcess waitForTermination(); int exitValue(); diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ChildProcessImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ChildProcessImpl.java index b9e075dfab7..367688f0bb4 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ChildProcessImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ChildProcessImpl.java @@ -7,6 +7,8 @@ import java.nio.file.Path; /** * Represents a forked child process that still exists or has terminated. + * + * @author hakonhall */ public class ChildProcessImpl implements ChildProcess { private final Process process; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/Command.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/Command.java index 72aa5b0df2d..049490f2705 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/Command.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/Command.java @@ -13,6 +13,11 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.stream.Collectors; +/** + * Class to fork and exec a program, and gets its exit status and output. + * + * @author hakonhall + */ public class Command { private static Logger logger = Logger.getLogger(Command.class.getName()); private static Pattern ARGUMENT_PATTERN = Pattern.compile("^[a-zA-Z0-9=@%/+:.,_-]+$"); diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/CommandException.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/CommandException.java index ae84c876b35..148f2102ddf 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/CommandException.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/process/CommandException.java @@ -1,6 +1,9 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.node.admin.task.util.process; +/** + * @author hakonhall + */ @SuppressWarnings("serial") public class CommandException extends RuntimeException { public CommandException(String message) { diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/AddYumRepo.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/AddYumRepo.java index 32c97c76615..2b1cbbed974 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/AddYumRepo.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/AddYumRepo.java @@ -7,6 +7,9 @@ import com.yahoo.vespa.hosted.node.admin.task.util.file.FileWriter; import java.nio.file.Path; import java.util.regex.Pattern; +/** + * @author hakonhall + */ public class AddYumRepo { private static final Pattern REPOSITORY_ID_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]+$"); diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java index 3ca20cba99a..c1514f1056b 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java @@ -12,6 +12,9 @@ import java.util.Optional; import java.util.function.Supplier; import java.util.logging.Logger; +/** + * @author hakonhall + */ public class Yum { private static Logger logger = Logger.getLogger(Yum.class.getName()); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelperTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelperTest.java new file mode 100644 index 00000000000..723b9f0df8a --- /dev/null +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelperTest.java @@ -0,0 +1,35 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +package com.yahoo.vespa.hosted.node.admin.provider; + +import org.junit.Test; + +import java.util.Collections; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class DebugHandlerHelperTest { + @Test + public void trivial() { + DebugHandlerHelper helper = new DebugHandlerHelper(); + helper.addConstant("constant-key", "constant-value"); + + NodeAdminDebugHandler handler = new NodeAdminDebugHandler() { + @Override + public Map<String, Object> getDebugPage() { + return Collections.singletonMap("handler-value-key", "handler-value-value"); + } + }; + helper.addHandler("handler-key", handler); + + helper.addThreadSafeSupplier("supplier-key", () -> "supplier-value"); + + assertEquals("{" + + "supplier-key=supplier-value, " + + "handler-key={handler-value-key=handler-value-value}, " + + "constant-key=constant-value" + + "}", + helper.getDebugPage().toString()); + } +}
\ No newline at end of file diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileSyncTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileSyncTest.java index 71cd312d5d6..44868e17464 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileSyncTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/FileSyncTest.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.node.admin.task.util.file; +import com.yahoo.vespa.test.file.TestFileSystem; import org.junit.Test; import java.nio.file.FileSystem; @@ -18,7 +19,7 @@ import static org.junit.Assert.assertTrue; public class FileSyncTest { private final TestTaskContext taskContext = new TestTaskContext(); - private final FileSystem fileSystem = taskContext.fileSystem(); + private final FileSystem fileSystem = TestFileSystem.create(); private final Path path = fileSystem.getPath("/dir/file.txt"); private final UnixPath unixPath = new UnixPath(path); @@ -80,4 +81,4 @@ public class FileSyncTest { actualMods = taskContext.getSystemModificationLog(); assertEquals(new ArrayList<>(), actualMods); } -}
\ No newline at end of file +} diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TestTaskContext.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TestTaskContext.java index d023a11671e..757f3004683 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TestTaskContext.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TestTaskContext.java @@ -2,8 +2,8 @@ package com.yahoo.vespa.hosted.node.admin.task.util.file; +import com.yahoo.vespa.hosted.node.admin.component.IdempotentTask; import com.yahoo.vespa.hosted.node.admin.component.TaskContext; -import com.yahoo.vespa.test.file.TestFileSystem; import java.nio.file.FileSystem; import java.util.ArrayList; @@ -12,22 +12,21 @@ import java.util.List; import java.util.logging.Logger; public class TestTaskContext implements TaskContext { - private final FileSystem fileSystem = TestFileSystem.create(); private final List<String> logs = new ArrayList<>(); @Override public Cloud cloud() { - return Cloud.YAHOO; + throw new UnsupportedOperationException(); } @Override public EnumSet<Role> roles() { - return EnumSet.of(Role.CONFIG_SERVER_DOCKER_HOST); + throw new UnsupportedOperationException(); } @Override public FileSystem fileSystem() { - return fileSystem; + throw new UnsupportedOperationException(); } @Override @@ -42,4 +41,9 @@ public class TestTaskContext implements TaskContext { public void clearSystemModificationLog() { logs.clear(); } + + @Override + public boolean executeSubtask(IdempotentTask task) { + throw new UnsupportedOperationException(); + } } |