Skip to content

Commit

Permalink
Revert "camel-jbang-plugin-k: infer the dependencies by inspecting th…
Browse files Browse the repository at this point in the history
…e route …" (#13404)

This reverts commit 897b814.
  • Loading branch information
claudio4j committed Mar 11, 2024
1 parent 699cf33 commit 1957436
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 281 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.k;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -26,9 +25,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
Expand All @@ -45,8 +42,6 @@
import org.apache.camel.github.GitHubResourceResolver;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.engine.DefaultResourceResolvers;
import org.apache.camel.main.KameletMain;
import org.apache.camel.main.download.DownloadListener;
import org.apache.camel.spi.ResourceResolver;
import org.apache.camel.util.FileUtil;
import org.apache.camel.util.IOHelper;
Expand All @@ -72,11 +67,6 @@
@Command(name = "run", description = "Run Camel integrations on Kubernetes", sortOptions = false)
public class IntegrationRun extends KubeBaseCommand {

// ignored list of dependencies, can be either groupId or artifactId
// as camel-k loads dependencies from the catalog produced by camel-k-runtime, some camel core dependencies
// are not available, so we have to skip them
private static final String[] SKIP_DEPS = new String[] { "camel-core-languages", "camel-endpointdsl" };

@CommandLine.Parameters(description = "The Camel file(s) to run.",
arity = "0..9", paramLabel = "<files>")
String[] filePaths;
Expand Down Expand Up @@ -180,7 +170,6 @@ public class IntegrationRun extends KubeBaseCommand {

public IntegrationRun(CamelJBangMain main) {
super(main);
Arrays.sort(SKIP_DEPS);
}

public Integer doCall() throws Exception {
Expand All @@ -193,6 +182,17 @@ public Integer doCall() throws Exception {
integration.getMetadata()
.setName(getIntegrationName(integrationSources));

if (dependencies != null && dependencies.length > 0) {
List<String> deps = new ArrayList<>();
for (String dependency : dependencies) {
String normalized = normalizeDependency(dependency);
validateDependency(normalized, printer());
deps.add(normalized);
}

integration.getSpec().setDependencies(deps);
}

if (kit != null) {
IntegrationKit integrationKit = new IntegrationKit();
integrationKit.setName(kit);
Expand Down Expand Up @@ -246,17 +246,6 @@ public Integer doCall() throws Exception {
} else {
List<Source> resolvedSources = resolveSources(integrationSources);

Set<String> intDependencies = calculateDependencies(resolvedSources);
if (dependencies != null && dependencies.length > 0) {
for (String dependency : dependencies) {
String normalized = normalizeDependency(dependency);
validateDependency(normalized, printer());
intDependencies.add(normalized);
}
}
List<String> deps = new ArrayList<>(intDependencies);
integration.getSpec().setDependencies(deps);

List<Flows> flows = new ArrayList<>();
List<Sources> sources = new ArrayList<>();
for (Source source : resolvedSources) {
Expand Down Expand Up @@ -415,22 +404,22 @@ private Source resolveSource(String source) {
}
}

private List<Source> resolveSources(List<String> sourcePaths) {
private List<Source> resolveSources(List<String> sources) {
List<Source> resolved = new ArrayList<>();
for (String sourcePath : sourcePaths) {
SourceScheme sourceScheme = SourceScheme.fromUri(sourcePath);
String fileExtension = FileUtil.onlyExt(sourcePath);
String fileName = SourceScheme.onlyName(FileUtil.onlyName(sourcePath)) + "." + fileExtension;
for (String source : sources) {
SourceScheme sourceScheme = SourceScheme.fromUri(source);
String fileExtension = FileUtil.onlyExt(source);
String fileName = SourceScheme.onlyName(FileUtil.onlyName(source)) + "." + fileExtension;
try {
switch (sourceScheme) {
case GIST -> {
StringJoiner all = new StringJoiner(",");
GistHelper.fetchGistUrls(sourcePath, all);
GistHelper.fetchGistUrls(source, all);

try (ResourceResolver resolver = new GistResourceResolver()) {
for (String uri : all.toString().split(",")) {
resolved.add(new Source(
fileName, sourcePath,
fileName,
IOHelper.loadText(resolver.resolve(uri).getInputStream()),
fileExtension, compression, false));
}
Expand All @@ -439,53 +428,52 @@ private List<Source> resolveSources(List<String> sourcePaths) {
case HTTP -> {
try (ResourceResolver resolver = new DefaultResourceResolvers.HttpResolver()) {
resolved.add(new Source(
fileName, sourcePath,
IOHelper.loadText(resolver.resolve(sourcePath).getInputStream()),
fileName,
IOHelper.loadText(resolver.resolve(source).getInputStream()),
fileExtension, compression, false));
}
}
case HTTPS -> {
try (ResourceResolver resolver = new DefaultResourceResolvers.HttpsResolver()) {
resolved.add(new Source(
fileName, sourcePath,
IOHelper.loadText(resolver.resolve(sourcePath).getInputStream()),
fileName,
IOHelper.loadText(resolver.resolve(source).getInputStream()),
fileExtension, compression, false));
}
}
case FILE -> {
try (ResourceResolver resolver = new DefaultResourceResolvers.FileResolver()) {
resolved.add(new Source(
fileName, sourcePath,
IOHelper.loadText(resolver.resolve(sourcePath).getInputStream()),
fileName,
IOHelper.loadText(resolver.resolve(source).getInputStream()),
fileExtension, compression, true));
}
}
case CLASSPATH -> {
try (ResourceResolver resolver = new DefaultResourceResolvers.ClasspathResolver()) {
resolver.setCamelContext(new DefaultCamelContext());
resolved.add(new Source(
fileName, sourcePath,
IOHelper.loadText(resolver.resolve(sourcePath).getInputStream()),
fileName,
IOHelper.loadText(resolver.resolve(source).getInputStream()),
fileExtension, compression, true));
}
}
case GITHUB, RAW_GITHUB -> {
StringJoiner all = new StringJoiner(",");
GitHubHelper.fetchGithubUrls(sourcePath, all);
GitHubHelper.fetchGithubUrls(source, all);

try (ResourceResolver resolver = new GitHubResourceResolver()) {
for (String uri : all.toString().split(",")) {
resolved.add(new Source(
fileName, sourcePath,
fileName,
IOHelper.loadText(resolver.resolve(uri).getInputStream()),
fileExtension, compression, false));
}
}
}
case UNKNOWN -> {
try (FileInputStream fis = new FileInputStream(sourcePath)) {
resolved.add(
new Source(fileName, sourcePath, IOHelper.loadText(fis), fileExtension, compression, true));
try (FileInputStream fis = new FileInputStream(source)) {
resolved.add(new Source(fileName, IOHelper.loadText(fis), fileExtension, compression, true));
}
}
}
Expand Down Expand Up @@ -552,7 +540,7 @@ private static void validateDependency(String dependency, Printer printer) {
}
}

private record Source(String name, String path, String content, String extension, boolean compressed, boolean local) {
private record Source(String name, String content, String extension, boolean compressed, boolean local) {

/**
* Provides source contant and automatically handles compression of content when enabled.
Expand Down Expand Up @@ -580,92 +568,4 @@ public boolean isYaml() {
}
}

private Set<String> calculateDependencies(List<Source> resolvedSources) throws Exception {
List<String> files = new ArrayList<>();
for (Source s : resolvedSources) {
if (s.local && !s.path.startsWith("classpath:")) {
// get the absolute path for a local file
files.add("file://" + new File(s.path).getAbsolutePath());
} else {
files.add(s.path);
}
}
final KameletMain main = new KameletMain();
// main.setDownload(false);
main.setFresh(false);
RunDownloadListener downloadListener = new RunDownloadListener(resolvedSources);
main.setDownloadListener(downloadListener);
main.setSilent(true);
// enable stub in silent mode so we do not use real components
main.setStubPattern("*");
// do not run for very long in silent run
main.addInitialProperty("camel.main.autoStartup", "false");
main.addInitialProperty("camel.main.durationMaxSeconds", "1");
main.addInitialProperty("camel.jbang.verbose", "false");
main.addInitialProperty("camel.main.routesIncludePattern", String.join(",", files));

main.start();
main.run();

main.stop();
main.shutdown();
return downloadListener.getDependencies();
}

private static class RunDownloadListener implements DownloadListener {

final Set<String> dependencies = new TreeSet<>();
private final List<Source> resolvedSources;

public RunDownloadListener(List<Source> resolvedSources) {
this.resolvedSources = resolvedSources;
}

@Override
public void onDownloadDependency(String groupId, String artifactId, String version) {
if (!skipArtifact(groupId, artifactId)) {
// format: camel:<component name>
// KameletMain is used to resolve the dependencies and it already contains
// camel-kamelets and camel-rest artifacts, then the source code must be inspected
// to actually add them if they are used in the route.
if ("camel-rest".equals(artifactId) && routeContainsEndpoint("rest")) {
dependencies.add("camel:" + artifactId.replace("camel-", ""));
}
if (("camel-kamelet".equals(artifactId) || "camel-yaml-dsl".equals(artifactId))
&& routeContainsEndpoint("kamelet")) {
dependencies.add("camel:" + artifactId.replace("camel-", ""));
}
if (!"camel-rest".equals(artifactId) && !"camel-kamelet".equals(artifactId)
&& !"camel-yaml-dsl".equals(artifactId)) {
dependencies.add("camel:" + artifactId.replace("camel-", ""));
}
}
}

private boolean skipArtifact(String groupId, String artifactId) {
return Arrays.binarySearch(SKIP_DEPS, artifactId) >= 0 || Arrays.binarySearch(SKIP_DEPS, groupId) >= 0;
}

// inspect the source code to determine if it contains a specific endpoint
private boolean routeContainsEndpoint(String componentName) {
boolean contains = false;
for (Source source : resolvedSources) {
// find if the route contains the component with the format: <component>:
if (source.content.contains(componentName + ":")) {
contains = true;
break;
}
}
return contains;
}

@Override
public void onAlreadyDownloadedDependency(String groupId, String artifactId, String version) {
}

private Set<String> getDependencies() {
return dependencies;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package org.apache.camel.dsl.jbang.core.commands.k;

import java.util.Arrays;
import java.util.regex.Pattern;

import org.apache.camel.RuntimeCamelException;
Expand Down Expand Up @@ -200,63 +199,6 @@ public void shouldAddDependencies() throws Exception {
traits: {}""", printer.getOutput());
}

@Test
public void shouldInferDependenciesYamlRoute() throws Exception {
IntegrationRun command = createCommand();
command.filePaths = new String[] { "classpath:route-deps.yaml" };
command.output = "yaml";
command.doCall();

String[] specDependencies = getDependencies(printer.getOutput());
String[] deps = new String[] {
"camel:caffeine", "camel:http", "camel:jackson", "camel:jsonpath", "camel:log", "camel:timer" };
Assertions.assertArrayEquals(deps, specDependencies, "Dependencies don't match: " + Arrays.toString(specDependencies));
}

@Test
public void shouldAddComplexDependenciesYamlRoute() throws Exception {
IntegrationRun command = createCommand();
command.filePaths = new String[] { "classpath:route-deps.yaml" };
command.dependencies = new String[] { "camel-twitter", "mvn:foo:bar:1.0" };
command.output = "yaml";
command.doCall();

String[] specDependencies = getDependencies(printer.getOutput());
String[] deps = new String[] {
"camel:caffeine", "camel:http", "camel:jackson", "camel:jsonpath", "camel:log", "camel:timer", "camel:twitter",
"mvn:foo:bar:1.0" };
Assertions.assertArrayEquals(deps, specDependencies, "Dependencies don't match: " + Arrays.toString(specDependencies));
}

@Test
public void shouldInferDependenciesJavaRoute() throws Exception {
IntegrationRun command = createCommand();
command.filePaths = new String[] { "classpath:Sample.java" };
command.output = "yaml";
command.doCall();

String[] specDependencies = getDependencies(printer.getOutput());
String[] deps = new String[] {
"camel:aws2-s3", "camel:caffeine", "camel:dropbox", "camel:jacksonxml", "camel:java-joor-dsl", "camel:kafka",
"camel:mongodb", "camel:telegram", "camel:zipfile" };
Assertions.assertArrayEquals(deps, specDependencies, "Dependencies don't match: " + Arrays.toString(specDependencies));
}

@Test
public void shouldAddComplexDependenciesJavaRoute() throws Exception {
IntegrationRun command = createCommand();
command.filePaths = new String[] { "classpath:Sample.java" };
command.dependencies = new String[] { "camel-twitter", "mvn:foo:bar:1.0" };
command.output = "yaml";
command.doCall();

String[] specDependencies = getDependencies(printer.getOutput());
String[] deps = new String[] {
"camel:aws2-s3", "camel:caffeine", "camel:dropbox", "camel:jacksonxml", "camel:java-joor-dsl", "camel:kafka",
"camel:mongodb", "camel:telegram", "camel:twitter", "camel:zipfile", "mvn:foo:bar:1.0" };
Assertions.assertArrayEquals(deps, specDependencies, "Dependencies don't match: " + Arrays.toString(specDependencies));
}

@Test
public void shouldAddEnvVars() throws Exception {
IntegrationRun command = createCommand();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.KubernetesCrudDispatcher;
Expand All @@ -38,7 +36,6 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInstance;
import org.yaml.snakeyaml.Yaml;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class KubeBaseTest {
Expand Down Expand Up @@ -93,14 +90,4 @@ protected Integration createIntegration(String name) throws IOException {
return created;
}

protected String[] getDependencies(String yamlSource) {
Yaml yaml = new Yaml();
Map<String, Object> obj = yaml.load(yamlSource);
//noinspection unchecked
obj = (Map<String, Object>) obj.get("spec");
//noinspection unchecked
List<String> specDeps = (List<String>) obj.get("dependencies");
return specDeps.toArray(new String[specDeps.size()]);
}

}

0 comments on commit 1957436

Please sign in to comment.