Skip to content

Commit 146937c

Browse files
committed
wip
1 parent 59824d1 commit 146937c

File tree

3 files changed

+73
-10
lines changed

3 files changed

+73
-10
lines changed

api/src/main/java/io/kafbat/ui/config/auth/RoleBasedAccessControlProperties.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
public class RoleBasedAccessControlProperties {
1111

1212
private final List<Role> roles = new ArrayList<>();
13+
// private String haha;
14+
1315

1416
@PostConstruct
1517
public void init() {

api/src/main/java/io/kafbat/ui/service/app/ConfigReloadService.java

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
package io.kafbat.ui.service.app;
22

3+
import io.kafbat.ui.config.auth.RoleBasedAccessControlProperties;
4+
import io.kafbat.ui.service.rbac.AccessControlService;
35
import io.kafbat.ui.util.MultiFileWatcher;
46
import jakarta.annotation.PostConstruct;
57
import jakarta.annotation.PreDestroy;
68
import java.io.IOException;
9+
import java.io.InputStream;
10+
import java.nio.file.Files;
711
import java.nio.file.Paths;
812
import java.util.LinkedHashSet;
913
import java.util.Objects;
14+
import java.util.Properties;
1015
import java.util.stream.Collectors;
1116
import java.util.stream.Stream;
1217
import java.util.stream.StreamSupport;
18+
import lombok.Cleanup;
1319
import lombok.RequiredArgsConstructor;
1420
import lombok.extern.slf4j.Slf4j;
21+
import org.springframework.beans.factory.ObjectProvider;
22+
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
23+
import org.springframework.boot.context.properties.bind.Binder;
1524
import org.springframework.boot.env.OriginTrackedMapPropertySource;
1625
import org.springframework.boot.origin.Origin;
1726
import org.springframework.boot.origin.OriginTrackedValue;
1827
import org.springframework.boot.origin.TextResourceOrigin;
28+
import org.springframework.context.ApplicationContext;
1929
import org.springframework.core.env.ConfigurableEnvironment;
30+
import org.springframework.core.env.MutablePropertySources;
31+
import org.springframework.core.env.PropertiesPropertySource;
32+
import org.springframework.core.env.PropertySource;
2033
import org.springframework.core.io.Resource;
2134
import org.springframework.stereotype.Service;
2235

@@ -29,10 +42,14 @@ public class ConfigReloadService {
2942
private static final String THREAD_NAME = "config-watcher-thread";
3043

3144
private final ConfigurableEnvironment environment;
45+
private final ApplicationContext appContext;
3246

3347
private Thread watcherThread;
3448
private MultiFileWatcher multiFileWatcher;
3549

50+
private final ObjectProvider<AccessControlService> accessControlService;
51+
private final ObjectProvider<RoleBasedAccessControlProperties> roleBasedAccessControlProperties;
52+
3653
@PostConstruct
3754
public void init() {
3855
var propertySourcePaths = StreamSupport.stream(environment.getPropertySources().spliterator(), false)
@@ -69,7 +86,28 @@ public void init() {
6986
log.debug("Auto reload is enabled, will watch for config changes");
7087

7188
try {
72-
this.multiFileWatcher = new MultiFileWatcher(propertySourcePaths, this::reload);
89+
this.multiFileWatcher = new MultiFileWatcher(propertySourcePaths, path -> {
90+
System.out.println(path);
91+
var propertySources = environment.getPropertySources();
92+
93+
94+
95+
Properties properties = new Properties();
96+
try {
97+
@Cleanup InputStream inputStream = Files.newInputStream(Paths.get("/tmp/kek.yaml"));
98+
properties.load(inputStream);
99+
} catch (IOException e) {
100+
throw new RuntimeException(e);
101+
}
102+
103+
PropertySource<?> origin =
104+
propertySources.stream().filter(ps -> ps.getName().contains("tmp/kek")).findFirst().get();
105+
environment.getPropertySources().replace(origin.getName(), new PropertiesPropertySource(origin.getName(), properties));
106+
107+
System.out.println();
108+
var kekw = appContext.getBean(AccessControlService.class);
109+
return null;
110+
});
73111
this.watcherThread = new Thread(multiFileWatcher::watchLoop, THREAD_NAME);
74112
this.watcherThread.start();
75113
} catch (IOException e) {
@@ -91,6 +129,19 @@ public void shutdown() {
91129
}
92130

93131
private void reload() {
132+
var registry = (DefaultSingletonBeanRegistry) appContext.getAutowireCapableBeanFactory();
133+
134+
registry.destroySingleton("AccessControlService");
135+
136+
Binder.get(environment)
137+
.bind("rbac", RoleBasedAccessControlProperties.class)
138+
.orElseThrow(() -> new IllegalStateException("no rbac config"));
139+
140+
var newProps = appContext.getBean(AccessControlService.class);
141+
newProps.init();
142+
// accessControlService.init();
143+
System.out.println();
144+
94145

95146
}
96147

api/src/main/java/io/kafbat/ui/util/MultiFileWatcher.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.nio.file.FileSystems;
1212
import java.nio.file.Files;
1313
import java.nio.file.Path;
14+
import java.nio.file.Paths;
1415
import java.nio.file.WatchKey;
1516
import java.nio.file.WatchService;
1617
import java.time.Duration;
@@ -19,8 +20,11 @@
1920
import java.util.Map;
2021
import java.util.Optional;
2122
import java.util.Set;
23+
import java.util.concurrent.Callable;
2224
import java.util.concurrent.ConcurrentHashMap;
25+
import java.util.function.Function;
2326
import lombok.extern.slf4j.Slf4j;
27+
import org.jetbrains.annotations.NotNull;
2428
import org.springframework.util.Assert;
2529

2630
@Slf4j
@@ -31,11 +35,11 @@ public final class MultiFileWatcher implements AutoCloseable {
3135
private final WatchService watchService = FileSystems.getDefault().newWatchService();
3236
private final Set<Path> watchedFiles = ConcurrentHashMap.newKeySet();
3337
private final Map<WatchKey, Path> watchDirsByKey = new HashMap<>();
34-
private final Runnable reloader;
38+
private final Function<Path, Void> reloader;
3539

3640
private long lastTriggerAt = 0;
3741

38-
public MultiFileWatcher(Collection<Path> filesToWatch, Runnable reloader) throws IOException {
42+
public MultiFileWatcher(Collection<Path> filesToWatch, Function<Path, Void> reloader) throws IOException {
3943
Assert.notNull(reloader, "reloader must not be null");
4044
this.reloader = reloader;
4145

@@ -62,28 +66,28 @@ public MultiFileWatcher(Collection<Path> filesToWatch, Runnable reloader) throws
6266
log.trace("Watching files: {}", watchedFiles.stream().map(Path::toString).toList());
6367

6468
watchedFiles.stream()
65-
.map(p -> Optional.ofNullable(p.getParent()).orElse(Path.of(".")))
69+
// .map(getParentPath())
6670
.distinct()
67-
.forEach(dir -> {
71+
.forEach(file -> {
6872
try {
69-
var key = dir.register(watchService,
73+
var key = getParentPath().apply(file).register(watchService,
7074
ENTRY_MODIFY,
7175
ENTRY_CREATE, ENTRY_DELETE // watch these for atomic replacements
7276
);
73-
watchDirsByKey.put(key, dir);
77+
watchDirsByKey.put(key, file);
7478
} catch (IOException e) {
7579
throw new UncheckedIOException(e);
7680
}
7781
});
7882

79-
log.trace("Watching directories: {}", watchDirsByKey.values().stream().map(Path::toString).toList());
83+
log.trace("Watching directories: {}", watchDirsByKey.values().stream().map(a -> getParentPath().apply(a)).map(Path::toString).toList());
8084
}
8185

8286
public void watchLoop() {
8387
while (true) {
8488
try {
8589
var key = watchService.take();
86-
var dir = watchDirsByKey.get(key);
90+
var dir = getParentPath().apply(watchDirsByKey.get(key));
8791
if (dir == null) {
8892
continue;
8993
}
@@ -95,7 +99,8 @@ public void watchLoop() {
9599
.anyMatch(this::matchesTarget);
96100

97101
if (hit && shouldTrigger()) {
98-
reloader.run();
102+
var filePath = watchDirsByKey.get(key); // TODO
103+
reloader.apply(filePath);
99104
}
100105

101106
if (!key.reset()) {
@@ -144,5 +149,10 @@ private boolean shouldTrigger() {
144149
public void close() throws IOException {
145150
watchService.close();
146151
}
152+
153+
@NotNull
154+
private static Function<Path, Path> getParentPath() {
155+
return p -> Optional.ofNullable(p.getParent()).orElse(Path.of("."));
156+
}
147157
}
148158

0 commit comments

Comments
 (0)