From 17e24a70fed0f3ad046d74963c9a7f76a3ec4a37 Mon Sep 17 00:00:00 2001 From: "Jan N. Klug" Date: Sun, 26 Jun 2022 13:52:03 +0200 Subject: [PATCH] improvements Signed-off-by: Jan N. Klug --- .../service/WatchServiceFactoryImpl.java | 4 +- .../service/WatchServiceImpl.java | 52 +++++++++---------- .../service/WatchServiceImplTest.java | 3 +- .../internal/folder/FolderObserverTest.java | 7 ++- 4 files changed, 36 insertions(+), 30 deletions(-) rename bundles/org.openhab.core/src/main/java/org/openhab/core/{ => internal}/service/WatchServiceFactoryImpl.java (95%) rename bundles/org.openhab.core/src/main/java/org/openhab/core/{ => internal}/service/WatchServiceImpl.java (80%) rename bundles/org.openhab.core/src/test/java/org/openhab/core/{ => internal}/service/WatchServiceImplTest.java (98%) diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/service/WatchServiceFactoryImpl.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/internal/service/WatchServiceFactoryImpl.java similarity index 95% rename from bundles/org.openhab.core/src/main/java/org/openhab/core/service/WatchServiceFactoryImpl.java rename to bundles/org.openhab.core/src/main/java/org/openhab/core/internal/service/WatchServiceFactoryImpl.java index 06a36d02087..34518f7633e 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/service/WatchServiceFactoryImpl.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/internal/service/WatchServiceFactoryImpl.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.service; +package org.openhab.core.internal.service; import java.nio.file.Path; import java.util.Dictionary; @@ -20,6 +20,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.OpenHAB; +import org.openhab.core.service.WatchService; +import org.openhab.core.service.WatchServiceFactory; import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentException; import org.osgi.service.component.ComponentFactory; diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/service/WatchServiceImpl.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/internal/service/WatchServiceImpl.java similarity index 80% rename from bundles/org.openhab.core/src/main/java/org/openhab/core/service/WatchServiceImpl.java rename to bundles/org.openhab.core/src/main/java/org/openhab/core/internal/service/WatchServiceImpl.java index 8cda1c2c62b..3266ab0bb62 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/service/WatchServiceImpl.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/internal/service/WatchServiceImpl.java @@ -10,23 +10,20 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.service; +package org.openhab.core.internal.service; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import java.util.function.Predicate; -import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.common.ThreadPoolManager; +import org.openhab.core.service.WatchService; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; @@ -45,15 +42,14 @@ @NonNullByDefault @Component(factory = "org.openhab.core.service.watchservice.factory") public class WatchServiceImpl implements WatchService, DirectoryChangeListener { - private static final String THREAD_POOL_NAME = "file-processing"; - private final Logger logger = LoggerFactory.getLogger(WatchServiceImpl.class); - private final ScheduledExecutorService scheduler = ThreadPoolManager.getScheduledPool(THREAD_POOL_NAME); private final Path basePath; private final List dirPathListeners = new CopyOnWriteArrayList<>(); private final List subDirPathListeners = new CopyOnWriteArrayList<>(); + private final Thread watchThread; + private final DirectoryWatcher dirWatcher; private final String name; @@ -66,10 +62,16 @@ public WatchServiceImpl(Map config) throws IOException { logger.error("Tried to instantiate WatchService '{}' with missing configuration.", name); throw new IllegalArgumentException("Path to watch is missing."); } + try { basePath = Path.of(path).toAbsolutePath(); + if (!Files.exists(basePath)) { + logger.info("Watch directory '{}' does not exists. Trying to create it.", basePath); + Files.createDirectories(basePath); + } dirWatcher = DirectoryWatcher.builder().listener(this).path(basePath).build(); - // schedule immediately but make sure not in this thread as the implementation is blocking + watchThread = new Thread(dirWatcher::watch, name); + watchThread.start(); } catch (NoSuchFileException e) { // log message here, otherwise it'll be swallowed by the call to newInstance in the factory // also re-throw the exception to indicate that we failed @@ -81,19 +83,29 @@ public WatchServiceImpl(Map config) throws IOException { logger.warn("Could not instantiate WatchService '{}':", name, e); throw e; } - scheduler.schedule(dirWatcher::watch, 0, TimeUnit.SECONDS); } @Deactivate public void deactivate() throws IOException { dirWatcher.close(); + watchThread.interrupt(); } @Override public void registerListener(WatchEventListener watchEventListener, List paths, boolean withSubDirectories) { - List list = withSubDirectories ? this.subDirPathListeners : dirPathListeners; - paths.stream().map(this::toAbsolutePath).filter(Objects::nonNull) - .map(p -> new Listener((@NonNull Path) p, watchEventListener)).forEach(list::add); + for (Path path : paths) { + Path absolutePath = path.isAbsolute() ? path : basePath.resolve(path).toAbsolutePath(); + if (absolutePath.startsWith(basePath)) { + if (withSubDirectories) { + subDirPathListeners.add(new Listener(absolutePath, watchEventListener)); + } else { + dirPathListeners.add(new Listener(absolutePath, watchEventListener)); + } + } else { + logger.warn("Tried to add path '{}' to listener '{}', but the base path of this listener is '{}'", path, + name, basePath); + } + } } @Override @@ -102,18 +114,6 @@ public void unregisterListener(WatchEventListener watchEventListener) { dirPathListeners.removeIf(Listener.isListener(watchEventListener)); } - private @Nullable Path toAbsolutePath(Path path) { - if (path.isAbsolute()) { - if (path.startsWith(basePath)) { - return path; - } - logger.warn("Tried to add path '{}' to listener '{}', but the base path of this listener is '{}'", path, - name, basePath); - return null; - } - return basePath.resolve(path).toAbsolutePath(); - } - @Override public void onEvent(@Nullable DirectoryChangeEvent directoryChangeEvent) throws IOException { if (directoryChangeEvent == null || directoryChangeEvent.isDirectory() diff --git a/bundles/org.openhab.core/src/test/java/org/openhab/core/service/WatchServiceImplTest.java b/bundles/org.openhab.core/src/test/java/org/openhab/core/internal/service/WatchServiceImplTest.java similarity index 98% rename from bundles/org.openhab.core/src/test/java/org/openhab/core/service/WatchServiceImplTest.java rename to bundles/org.openhab.core/src/test/java/org/openhab/core/internal/service/WatchServiceImplTest.java index 48f7f1d8c48..642e68b9819 100644 --- a/bundles/org.openhab.core/src/test/java/org/openhab/core/service/WatchServiceImplTest.java +++ b/bundles/org.openhab.core/src/test/java/org/openhab/core/internal/service/WatchServiceImplTest.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.service; +package org.openhab.core.internal.service; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.empty; @@ -38,6 +38,7 @@ import org.openhab.core.JavaTest; import org.openhab.core.OpenHAB; import org.openhab.core.common.ThreadPoolManager; +import org.openhab.core.service.WatchService; import org.openhab.core.service.WatchService.Kind; /** diff --git a/itests/org.openhab.core.model.core.tests/src/main/java/org/openhab/core/model/core/internal/folder/FolderObserverTest.java b/itests/org.openhab.core.model.core.tests/src/main/java/org/openhab/core/model/core/internal/folder/FolderObserverTest.java index 65e4dfa4089..976d0d76d72 100644 --- a/itests/org.openhab.core.model.core.tests/src/main/java/org/openhab/core/model/core/internal/folder/FolderObserverTest.java +++ b/itests/org.openhab.core.model.core.tests/src/main/java/org/openhab/core/model/core/internal/folder/FolderObserverTest.java @@ -86,6 +86,8 @@ public class FolderObserverTest extends JavaOSGiTest { private static final String INITIAL_FILE_CONTENT = "Initial content"; + private static final String WATCH_SERVICE_NAME = "testWatcher"; + private @NonNullByDefault({}) Dictionary configProps; private @NonNullByDefault({}) String defaultWatchedDir; private @NonNullByDefault({}) FolderObserver folderObserver; @@ -124,7 +126,8 @@ private void setUpServices() throws IOException { when(contextMock.getProperties()).thenReturn(configProps); watchServiceFactory = getService(WatchServiceFactory.class); - watchService = watchServiceFactory.getWatchService("watcher", WATCHED_DIRECTORY.toPath()); + watchService = watchServiceFactory.getWatchService(WATCH_SERVICE_NAME, + WATCHED_DIRECTORY.toPath().toAbsolutePath()); modelRepo = new ModelRepoDummy(); folderObserver = new FolderObserver(modelRepo, readyServiceMock, watchService); @@ -140,7 +143,7 @@ private void setUpServices() throws IOException { @AfterEach public void tearDown() throws Exception { folderObserver.deactivate(); - watchServiceFactory.removeWatchService("watcher"); + watchServiceFactory.removeWatchService(WATCH_SERVICE_NAME); try (Stream walk = Files.walk(WATCHED_DIRECTORY.toPath())) { walk.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);