Commit ce6ade96 authored by Andrey Filippov's avatar Andrey Filippov

MCP FS access fine tuning, with examples

parent 8f31b82c
# Example MCP allowed-config file.
# Point -Delphel.mcp.allowed.configfile to this file.
# You can set either allowed.configdir or allowed.config.
#
# allowed.configdir=/media/elphel/btrfs-data/lwir16-proc/NC/config
# allowed.config=/media/elphel/btrfs-data/lwir16-proc/NC/config/MI184-v89-nc_site_30A-no_out.corr-xml
......@@ -17,11 +17,12 @@ import com.elphel.imagej.cameras.EyesisCorrectionParameters.CorrectionParameters
public class McpFsAccess {
private static final String PROP_ALLOWED_CONFIG = "elphel.mcp.allowed.config";
private static final String PROP_ALLOWED_CONFIG_DIR = "elphel.mcp.allowed.configdir";
private static final String PROP_ALLOWED_CONFIG_FILE = "elphel.mcp.allowed.configfile";
private static final String PROP_ALLOWED_EXTRA = "elphel.mcp.allowed.extra";
private static final String CONFIG_LIST_KEY = "CORRECTION_PARAMETERS.sourceSequencesList";
private static List<Path> cachedRoots = null;
private static String cachedConfig = null;
private static String cachedConfigKey = null;
private static long cachedConfigMtime = -1L;
private McpFsAccess() {
......@@ -30,16 +31,41 @@ public class McpFsAccess {
public static synchronized List<Path> getAllowedRoots() {
String configPath = System.getProperty(PROP_ALLOWED_CONFIG);
String configDir = System.getProperty(PROP_ALLOWED_CONFIG_DIR);
long mtime = getMtime(configPath, configDir);
if (cachedRoots != null && configEquals(configPath, cachedConfig) && mtime == cachedConfigMtime) {
String configFile = System.getProperty(PROP_ALLOWED_CONFIG_FILE);
String[] resolved = resolveConfigFromFile(configPath, configDir, configFile);
configPath = resolved[0];
configDir = resolved[1];
String cacheKey = buildCacheKey(configPath, configDir, configFile);
long mtime = getMtime(configPath, configDir, configFile);
if (cachedRoots != null && configEquals(cacheKey, cachedConfigKey) && mtime == cachedConfigMtime) {
return cachedRoots;
}
cachedRoots = buildAllowedRoots(configPath, configDir);
cachedConfig = configPath;
cachedConfigKey = cacheKey;
cachedConfigMtime = mtime;
return cachedRoots;
}
public static boolean hasConfig() {
String configPath = System.getProperty(PROP_ALLOWED_CONFIG);
String configDir = System.getProperty(PROP_ALLOWED_CONFIG_DIR);
String configFile = System.getProperty(PROP_ALLOWED_CONFIG_FILE);
String[] resolved = resolveConfigFromFile(configPath, configDir, configFile);
configPath = resolved[0];
configDir = resolved[1];
return (configPath != null && !configPath.trim().isEmpty())
|| (configDir != null && !configDir.trim().isEmpty());
}
public static void ensureConfigured() {
if (!hasConfig()) {
throw new IllegalStateException(
"MCP enabled but no allowed config specified. Set -Delphel.mcp.allowed.configdir "
+ "or -Delphel.mcp.allowed.config, or provide -Delphel.mcp.allowed.configfile "
+ "pointing to a file with allowed.configdir.");
}
}
public static boolean isAllowed(Path path) {
if (path == null) {
return false;
......@@ -200,16 +226,17 @@ public class McpFsAccess {
return -1L;
}
private static long getMtime(String configPath) {
if (configPath == null || configPath.trim().isEmpty()) {
return -1L;
}
private static long getMtime(String configPath, String configDir, String configFile) {
long max = getMtime(configPath, configDir);
if (configFile != null && !configFile.trim().isEmpty()) {
try {
return Files.getLastModifiedTime(Paths.get(configPath)).toMillis();
max = Math.max(max, Files.getLastModifiedTime(Paths.get(configFile)).toMillis());
} catch (IOException e) {
return -1L;
// ignore
}
}
return max;
}
private static boolean configEquals(String a, String b) {
if (a == null && b == null) {
......@@ -220,4 +247,58 @@ public class McpFsAccess {
}
return a.equals(b);
}
private static String buildCacheKey(String configPath, String configDir, String configFile) {
StringBuilder sb = new StringBuilder();
if (configPath != null) {
sb.append(configPath);
}
sb.append("|");
if (configDir != null) {
sb.append(configDir);
}
sb.append("|");
if (configFile != null) {
sb.append(configFile);
}
return sb.toString();
}
private static String[] resolveConfigFromFile(String configPath, String configDir, String configFile) {
if ((configPath != null && !configPath.trim().isEmpty())
|| (configDir != null && !configDir.trim().isEmpty())) {
return new String[] { configPath, configDir };
}
if (configFile == null || configFile.trim().isEmpty()) {
return new String[] { configPath, configDir };
}
Path filePath = Paths.get(configFile).toAbsolutePath().normalize();
if (!Files.exists(filePath)) {
return new String[] { configPath, configDir };
}
try {
List<String> lines = Files.readAllLines(filePath);
for (String line : lines) {
String trimmed = line.trim();
if (trimmed.isEmpty() || trimmed.startsWith("#")) {
continue;
}
int eq = trimmed.indexOf('=');
if (eq > 0) {
String key = trimmed.substring(0, eq).trim();
String value = trimmed.substring(eq + 1).trim();
if (key.equals(PROP_ALLOWED_CONFIG)) {
configPath = value;
} else if (key.equals(PROP_ALLOWED_CONFIG_DIR) || key.equals("allowed.configdir")) {
configDir = value;
}
} else if (configDir == null || configDir.trim().isEmpty()) {
configDir = trimmed;
}
}
} catch (IOException e) {
return new String[] { configPath, configDir };
}
return new String[] { configPath, configDir };
}
}
......@@ -30,6 +30,7 @@ public class McpServer {
if (INSTANCE != null) {
return INSTANCE;
}
McpFsAccess.ensureConfigured();
McpServer instance = new McpServer(owner, port);
instance.start();
INSTANCE = instance;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment