Skip to content

Commit

Permalink
[GENE-2434] - Vault token read from file.
Browse files Browse the repository at this point in the history
  • Loading branch information
puru-yanamala committed May 3, 2024
1 parent 0bfbfe3 commit 70e8f1e
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 4 deletions.
2 changes: 1 addition & 1 deletion lucene/default-nested-ivy-settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

<resolvers>
<ibiblio name="sonatype-releases" root="https://oss.sonatype.org/content/repositories/releases" m2compatible="true" />
<ibiblio name="maven.restlet.com" root="https://maven.restlet.com" m2compatible="true" />
<ibiblio name="maven.restlet.com" root="https://maven.restlet.talend.com" m2compatible="true" />
<ibiblio name="releases.cloudera.com" root="https://repository.cloudera.com/artifactory/libs-release-local" m2compatible="true" />

<filesystem name="local-maven-2" m2compatible="true" local="true">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (C) 2014 SilkCloud and/or its affiliates. All rights reserved.
*/

package org.apache.solr.handler.dataimport;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import static java.nio.file.StandardWatchEventKinds.*;

/**
* Java doc.
*/
public class FileWatcher {
//region singleton
private static volatile FileWatcher instance;

public static FileWatcher getInstance() {
// lazy singleton
if (instance == null) {
synchronized (FileWatcher.class) {
if (instance == null) {
FileWatcher instance = new FileWatcher();
instance.initialize();
FileWatcher.instance = instance;
}
}
}
return instance;
}

public static void setInstance(FileWatcher watcher) {
// setInstance for unit testing
instance = watcher;
}
//endregion

//region private fields
private static Logger logger = LoggerFactory.getLogger(FileWatcher.class);

private Thread thread;
private WatchService watchService;
private FileChangeListenerMap listeners = new FileChangeListenerMap();
//endregion

/**.
* File listener
*/
public interface FileListener {
void onFileChanged(Path path, WatchEvent.Kind<Path> kind);
}

public FileWatcher addListener(Path path, FileListener listener) {
try {
WatchKey key = path.register(watchService, ENTRY_CREATE, ENTRY_MODIFY);
listeners.addListener(key, listener);
}
catch (Exception ex) {
throw new RuntimeException(ex);
}

return this;
}

public void close() {
if (thread != null) {
thread.interrupt();
thread = null;
}
}

//region private methods

// protected empty constructor for subclassing/mocking
protected FileWatcher() {
}

private void initialize() {
try {
watchService = FileSystems.getDefault().newWatchService();
}
catch (IOException ex) {
throw new RuntimeException("Error creating watch service.", ex);
}
thread = new Thread(new Runnable() {
@Override
public void run() {
FileWatcher.this.run();
}
});
thread.start();
}

private void run() {
for (; ; ) {
try {
WatchKey key = watchService.take();
Path path = (Path) key.watchable();

for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();

if (kind == StandardWatchEventKinds.OVERFLOW) {
logger.warn("Overflow happened in FileWatcher for key " + key);
continue;
}

WatchEvent<Path> ev = (WatchEvent<Path>) event;
listeners.notify(key, path, ev.kind());
}
}
catch (InterruptedException ex) {
return;
}
catch (Exception ex) {
logger.warn("Error occurred in file watcher. ", ex);
}
}
}

//endregion

//region private classes

private static final class FileChangeListenerList {
private ArrayList<WeakReference<FileListener>> listeners = new ArrayList<>();

public void addListener(FileListener listener) {
listeners.add(new WeakReference<>(listener));
}

public void notify(Path path, WatchEvent.Kind<Path> kind) {
ArrayList<WeakReference<FileListener>> toRemove = new ArrayList<>();
for (WeakReference<FileListener> listenerWeakReference : listeners) {
FileListener listener = listenerWeakReference.get();
if (listener == null) {
toRemove.add(listenerWeakReference);
}
else {
try {
listener.onFileChanged(path, kind);
}
catch (Exception ex) {
logger.warn("Error occurred in file watcher. ", ex);
}
}
}
listeners.removeAll(toRemove);
}
}

private static final class FileChangeListenerMap {
private ConcurrentHashMap<WatchKey, FileChangeListenerList> listeners = new ConcurrentHashMap<>();

public void addListener(WatchKey watchKey, FileListener listener) {
FileChangeListenerList list = listeners.get(watchKey);
if (list == null) {
final FileChangeListenerList newList = new FileChangeListenerList();
list = listeners.putIfAbsent(watchKey, newList);
if (list == null) {
list = newList;
}
}
list.addListener(listener);
}

public void notify(WatchKey watchKey, Path path, WatchEvent.Kind<Path> kind) {
FileChangeListenerList list = listeners.get(watchKey);
if (list != null) {
list.notify(path, kind);
}
}
}

//endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,47 @@
import org.springframework.vault.support.VaultResponse;

import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.*;

public class VaultServiceImpl {
private static final String ENV_VAULT_TOKEN = "VAULT_TOKEN";
private static final String ENV_VAULT_AUTH_PATH = "VAULT_AUTH_PATH";
private static final String ENV_VAULT_ADDR = "VAULT_ADDR";
private static final String ENV_VAULT_PATH = "VAULT_PATH";
private static final String DATA = "data";

private static final String vaultTokenFilePath = System.getenv().getOrDefault(ENV_VAULT_AUTH_PATH, "/etc/vault/token");
private VaultTemplate vaultTemplate;
private String vaultToken;
private String vaultHost;

public VaultServiceImpl() {
try {
String vaultToken = System.getenv(ENV_VAULT_TOKEN);
String vaultHost = System.getenv(ENV_VAULT_ADDR);
vaultToken = getVaultToken();
vaultHost = System.getenv(ENV_VAULT_ADDR);
vaultTemplate = new VaultTemplate(VaultEndpoint.from(new URI(vaultHost)), new TokenAuthentication(vaultToken));
} catch (Exception e) {
throw new RuntimeException("Failed to connect to vault using token", e);
}
watchVaultFileUpdates();
}

private String getVaultToken() {
try {
List<String> lines = Files.readAllLines(Paths.get(vaultTokenFilePath));
if (!lines.isEmpty()) {
return lines.get(0);
} else {
throw new RuntimeException(vaultTokenFilePath + ": vault auth token file is empty.");
}
} catch (IOException e) {
throw new RuntimeException("Error reading vault auth token file", e);
}
}

public Properties readVaultProperties() {
Expand Down Expand Up @@ -58,4 +80,15 @@ private static Properties readVaultProperties(VaultResponse vaultResponse) {

return new Properties();
}

private void watchVaultFileUpdates() {
FileWatcher.getInstance().addListener(Paths.get(vaultTokenFilePath).getParent(), (path, kind) -> {
vaultToken = getVaultToken();
try {
vaultTemplate = new VaultTemplate(VaultEndpoint.from(new URI(vaultHost)), new TokenAuthentication(vaultToken));
} catch (Exception e) {
throw new RuntimeException("vault configuration is wrong", e);
}
});
}
}

0 comments on commit 70e8f1e

Please # to comment.