Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ default Map<String, String> translateProperties(String prefix, C config) {
return Collections.emptyMap();
}

/**
* Translates forage properties for export-time use. By default delegates to
* {@link #translateProperties(String, Config)}, but subclasses can override to skip
* runtime-only checks (e.g., classpath verification) that don't apply at export time.
*/
default Map<String, String> translatePropertiesForExport(String prefix, C config) {
return translateProperties(prefix, config);
}

/**
* Returns auxiliary bean descriptors (e.g., aggregation repos, idempotent repos)
* that should be created alongside the primary bean for the given prefix.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ public Map<String, String> translateProperties(String prefix, AgentConfig config
}
}

return translateModelProperties(modelKind, config);
}

@Override
public Map<String, String> translatePropertiesForExport(String prefix, AgentConfig config) {
String modelKind = config.modelKind();
if (modelKind == null) {
return Map.of();
}
return translateModelProperties(modelKind, config);
}

private Map<String, String> translateModelProperties(String modelKind, AgentConfig config) {
return switch (modelKind) {
case "ollama" -> translateOllamaProperties(config);
case "openai" -> translateOpenAiProperties(config);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.kaoto.forage.agent.AgentModuleDescriptor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.kaoto.forage.cxf.common.CxfModuleDescriptor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.kaoto.forage.jdbc.common.JdbcModuleDescriptor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.kaoto.forage.jms.common.JmsModuleDescriptor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.kaoto.forage.messaging.spring.rabbitmq.common.SpringRabbitMQModuleDescriptor
59 changes: 59 additions & 0 deletions tooling/camel-jbang-plugin-forage/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,65 @@
<version>${project.version}</version>
</dependency>

<!-- Module descriptors containing translateProperties/createConfig implementations
used at export time to convert forage.* properties to Quarkus-native format.
All transitive dependencies excluded — only the descriptor and config classes are needed. -->
<dependency>
<groupId>io.kaoto.forage</groupId>
<artifactId>forage-jdbc-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.kaoto.forage</groupId>
<artifactId>forage-jms-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.kaoto.forage</groupId>
<artifactId>forage-agent</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.kaoto.forage</groupId>
<artifactId>forage-cxf-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.kaoto.forage</groupId>
<artifactId>forage-spring-rabbitmq-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package io.kaoto.forage.plugin;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
import org.apache.camel.dsl.jbang.core.common.CamelJBangPlugin;
import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
import org.apache.camel.dsl.jbang.core.common.Plugin;
import org.apache.camel.dsl.jbang.core.common.PluginExporter;
import org.apache.camel.dsl.jbang.core.common.PluginRunCustomizer;
Expand All @@ -18,6 +22,7 @@
import org.slf4j.LoggerFactory;
import io.kaoto.forage.core.common.ExportCustomizer;
import io.kaoto.forage.core.common.RuntimeType;
import io.kaoto.forage.core.util.config.ConfigStore;
import io.kaoto.forage.plugin.config.ConfigCommand;
import io.kaoto.forage.plugin.config.ConfigReadCommand;
import io.kaoto.forage.plugin.config.ConfigWriteCommand;
Expand Down Expand Up @@ -53,8 +58,14 @@ public Optional<PluginRunCustomizer> getRunCustomizer() {
@Override
public Optional<PluginExporter> getExporter() {
return Optional.of(new PluginExporter() {

@Override
public Set<String> getDependencies(org.apache.camel.dsl.jbang.core.common.RuntimeType runtimeType) {
if (RuntimeType.quarkus.name().equals(runtimeType.name())) {
// mirrors ExportBaseCommand.BUILD_DIR (protected, not accessible from plugins)
Path buildDir = Path.of(CommandLineHelper.CAMEL_JBANG_WORK_DIR, "work");
translateForageProperties(buildDir);
}
// gather dependencies across all (enabled) export customizers for the specific runtime
return ExportHelper.getAllCustomizers()
.filter(ExportCustomizer::isEnabled)
Expand All @@ -74,6 +85,88 @@ public void addSourceFiles(Path buildDir, String packageName, Printer printer) {
});
}

private static void translateForageProperties(Path buildDir) {
String configDir = System.getProperty("forage.config.dir");
File workingDir = configDir != null ? new File(configDir) : new File(System.getProperty("user.dir"));

QuarkusPropertyTranslator.TranslationResult result;
try {
result = QuarkusPropertyTranslator.translate(workingDir);
} catch (IOException e) {
LOG.warn("Failed to scan forage properties for Quarkus translation: {}", e.getMessage());
return;
} finally {
// translate() populates the global ConfigStore singleton via config.register() — clean up
// so scanned values don't leak into subsequent operations in the same JVM
ConfigStore.getInstance().reload();
}

if (result.isEmpty()) {
return;
}

Path appPropsPath = buildDir.resolve("src/main/resources/application.properties");
if (!Files.exists(appPropsPath)) {
LOG.warn("application.properties not found at {} — skipping property translation", appPropsPath);
return;
}

try {
rewriteApplicationProperties(appPropsPath, result);
LOG.info("Translated {} forage properties to Quarkus-native format", result.propertyCount());
} catch (IOException e) {
LOG.warn("Failed to rewrite application.properties: {}", e.getMessage());
}
}

static void rewriteApplicationProperties(Path appPropsPath, QuarkusPropertyTranslator.TranslationResult result)
throws IOException {
List<String> originalLines = Files.readAllLines(appPropsPath);
Set<String> keysToRemove = result.translatedForageKeys();

// Keep every line except those whose key was translated to Quarkus format
Stream<String> filtered = originalLines.stream().filter(line -> {
String key = extractPropertyKey(line);
return key == null || !keysToRemove.contains(key);
});

// Append each translation group with a header showing the original forage properties
Stream<String> translated = result.groups().stream().flatMap(ForagePlugin::translationGroupToLines);

Files.write(appPropsPath, Stream.concat(filtered, translated).toList());
}

/**
* Extracts the property key from a .properties file line.
* Returns {@code null} for blank lines, comments, and lines without '='.
*/
private static String extractPropertyKey(String line) {
String trimmed = line.trim();
if (trimmed.isEmpty() || trimmed.startsWith("#") || trimmed.startsWith("!")) {
return null;
}
int eqIdx = trimmed.indexOf('=');
return eqIdx < 0 ? null : trimmed.substring(0, eqIdx).trim();
}

private static Stream<String> translationGroupToLines(QuarkusPropertyTranslator.TranslationGroup group) {
Stream.Builder<String> lines = Stream.builder();
lines.add("");
if (group.prefix() != null) {
lines.add("# Properties for " + group.moduleType() + " with prefix '" + group.prefix() + "'");
} else {
lines.add("# Properties for " + group.moduleType());
}
lines.add("# Translated from:");
group.sourceProperties().forEach((k, v) -> lines.add("# " + k + "=" + v));
group.properties().forEach((k, v) -> {
if (v != null) {
lines.add(k + "=" + v);
}
});
return lines.build();
}

private static final String SHIBBOLETH_REPO = "https://build.shibboleth.net/maven/releases/";

private void beforeRun(KameletMain main, List<String> files) {
Expand Down
Loading
Loading