@Test public void testReload() throws IOException { copyResourceTo("/net/morimekta/providence/config/files/base_service.cfg", temp.getRoot()); File stageDb = copyResourceTo("/net/morimekta/providence/config/files/stage_db.cfg", temp.getRoot()); File stage = copyResourceTo("/net/morimekta/providence/config/files/stage.cfg", temp.getRoot()); FileWatcher watcher = new FileWatcher(); ProvidenceConfig config = new ProvidenceConfig(registry, watcher, true); Supplier<Service> stage_service = config.resolveConfig(stage); assertEquals("{\n" + " name = \"stage\"\n" + " http = {\n" + " port = 8080\n" + " context = \"/app\"\n" + " signature_keys = {\n" + " \"app1\": b64(VGVzdCBPYXV0aCBLZXkK)\n" + " }\n" + " signature_override_keys = [\n" + " \"not_really_app_1\"\n" + " ]\n" + " }\n" + " db = {\n" + " uri = \"jdbc:h2:localhost:mem\"\n" + " driver = \"org.h2.Driver\"\n" + " credentials = {\n" + " username = \"myuser\"\n" + " password = \"MyP4s5w0rd\"\n" + " }\n" + " }\n" + "}", debugString(stage_service.get())); AtomicBoolean watcherCalled = new AtomicBoolean(false); watcher.addWatcher(file -> watcherCalled.set(true)); File tmp = temp.newFile(); writeContentTo(getResourceAsString("/net/morimekta/providence/config/files/stage_db2.cfg"), tmp); Files.move(tmp.toPath(), stageDb.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING); if (FileSystems.getDefault().newWatchService().getClass().getName().equals("sun.nio.fs.PollingWatchService")) { stageDb.setLastModified(System.currentTimeMillis() + 120*1000); } await().atMost(Duration.TEN_SECONDS).untilTrue(watcherCalled); assertThat(config.resolveConfig(stage), is(sameInstance(stage_service))); assertThat(stage_service.get(), is(sameInstance(stage_service.get()))); assertEquals("{\n" + " name = \"stage\"\n" + " http = {\n" + " port = 8080\n" + " context = \"/app\"\n" + " signature_keys = {\n" + " \"app1\": b64(VGVzdCBPYXV0aCBLZXkK)\n" + " }\n" + " signature_override_keys = [\n" + " \"not_really_app_1\"\n" + " ]\n" + " }\n" + " db = {\n" + " uri = \"jdbc:h2:localhost:mem\"\n" + " driver = \"org.h2.Driver\"\n" + " credentials = {\n" + " username = \"myuser\"\n" + " password = \"O7h3rP4ssw0rd\"\n" + " }\n" + " }\n" + "}", debugString(stage_service.get())); }
@Nonnull @Override @SuppressWarnings("unchecked") public <M extends PMessage<M, F>, F extends PField> ConfigSupplier<M, F> resolveConfig(@Nonnull File configFile, @Nullable ConfigSupplier<M, F> parentConfig) throws ProvidenceConfigException { Path configPath = canonicalFileLocation(configFile.toPath()); String path = null; if (parentConfig == null) { path = configPath.toString(); if (loaded.containsKey(path)) { return (ConfigSupplier<M, F>) loaded.get(path); } } ProvidenceConfigSupplier<M, F> supplier = new ProvidenceConfigSupplier<>( configFile, parentConfig, watcher, parser, clock); if (parentConfig == null) { loaded.put(path, supplier); } return supplier; }
ProvidenceConfig implements ConfigResolver { @Nonnull @Override @SuppressWarnings("unchecked") public <M extends PMessage<M, F>, F extends PField> ConfigSupplier<M, F> resolveConfig(@Nonnull File configFile, @Nullable ConfigSupplier<M, F> parentConfig) throws ProvidenceConfigException { Path configPath = canonicalFileLocation(configFile.toPath()); String path = null; if (parentConfig == null) { path = configPath.toString(); if (loaded.containsKey(path)) { return (ConfigSupplier<M, F>) loaded.get(path); } } ProvidenceConfigSupplier<M, F> supplier = new ProvidenceConfigSupplier<>( configFile, parentConfig, watcher, parser, clock); if (parentConfig == null) { loaded.put(path, supplier); } return supplier; } }
ProvidenceConfig implements ConfigResolver { @Nonnull @Override @SuppressWarnings("unchecked") public <M extends PMessage<M, F>, F extends PField> ConfigSupplier<M, F> resolveConfig(@Nonnull File configFile, @Nullable ConfigSupplier<M, F> parentConfig) throws ProvidenceConfigException { Path configPath = canonicalFileLocation(configFile.toPath()); String path = null; if (parentConfig == null) { path = configPath.toString(); if (loaded.containsKey(path)) { return (ConfigSupplier<M, F>) loaded.get(path); } } ProvidenceConfigSupplier<M, F> supplier = new ProvidenceConfigSupplier<>( configFile, parentConfig, watcher, parser, clock); if (parentConfig == null) { loaded.put(path, supplier); } return supplier; } ProvidenceConfig(TypeRegistry registry);  ProvidenceConfig(@Nonnull TypeRegistry registry,
                            @Nullable FileWatcher watcher, boolean strict);  ProvidenceConfig(@Nonnull TypeRegistry registry,
                            @Nullable FileWatcher watcher,
                            boolean strict,
                            @Nonnull Clock clock); }
ProvidenceConfig implements ConfigResolver { @Nonnull @Override @SuppressWarnings("unchecked") public <M extends PMessage<M, F>, F extends PField> ConfigSupplier<M, F> resolveConfig(@Nonnull File configFile, @Nullable ConfigSupplier<M, F> parentConfig) throws ProvidenceConfigException { Path configPath = canonicalFileLocation(configFile.toPath()); String path = null; if (parentConfig == null) { path = configPath.toString(); if (loaded.containsKey(path)) { return (ConfigSupplier<M, F>) loaded.get(path); } } ProvidenceConfigSupplier<M, F> supplier = new ProvidenceConfigSupplier<>( configFile, parentConfig, watcher, parser, clock); if (parentConfig == null) { loaded.put(path, supplier); } return supplier; } ProvidenceConfig(TypeRegistry registry);  ProvidenceConfig(@Nonnull TypeRegistry registry,
                            @Nullable FileWatcher watcher, boolean strict);  ProvidenceConfig(@Nonnull TypeRegistry registry,
                            @Nullable FileWatcher watcher,
                            boolean strict,
                            @Nonnull Clock clock); @Nonnull @Override @SuppressWarnings("unchecked") ConfigSupplier<M, F> resolveConfig(@Nonnull File configFile,
                                       @Nullable ConfigSupplier<M, F> parentConfig); @Nonnull M getConfig(@Nonnull File configFile); @Nonnull M getConfig(@Nonnull File configFile, @Nonnull M parent); }
ProvidenceConfig implements ConfigResolver { @Nonnull @Override @SuppressWarnings("unchecked") public <M extends PMessage<M, F>, F extends PField> ConfigSupplier<M, F> resolveConfig(@Nonnull File configFile, @Nullable ConfigSupplier<M, F> parentConfig) throws ProvidenceConfigException { Path configPath = canonicalFileLocation(configFile.toPath()); String path = null; if (parentConfig == null) { path = configPath.toString(); if (loaded.containsKey(path)) { return (ConfigSupplier<M, F>) loaded.get(path); } } ProvidenceConfigSupplier<M, F> supplier = new ProvidenceConfigSupplier<>( configFile, parentConfig, watcher, parser, clock); if (parentConfig == null) { loaded.put(path, supplier); } return supplier; } ProvidenceConfig(TypeRegistry registry);  ProvidenceConfig(@Nonnull TypeRegistry registry,
                            @Nullable FileWatcher watcher, boolean strict);  ProvidenceConfig(@Nonnull TypeRegistry registry,
                            @Nullable FileWatcher watcher,
                            boolean strict,
                            @Nonnull Clock clock); @Nonnull @Override @SuppressWarnings("unchecked") ConfigSupplier<M, F> resolveConfig(@Nonnull File configFile,
                                       @Nullable ConfigSupplier<M, F> parentConfig); @Nonnull M getConfig(@Nonnull File configFile); @Nonnull M getConfig(@Nonnull File configFile, @Nonnull M parent);  }