Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dsl): camel jbang export property #16901

Merged
merged 1 commit into from
Jan 23, 2025
Merged
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 @@ -160,6 +160,7 @@ protected Integer export(ExportBaseCommand cmd) throws Exception {
cmd.excludes = this.excludes;
cmd.ignoreLoadingError = this.ignoreLoadingError;
cmd.lazyBean = this.lazyBean;
cmd.applicationProperties = this.applicationProperties;
// run export
return cmd.export();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ public abstract class ExportBaseCommand extends CamelCommand {
description = "Maven/Gradle build properties, ex. --build-property=prop1=foo")
protected List<String> buildProperties = new ArrayList<>();

@CommandLine.Option(names = { "--property" },
description = "Camel application properties, ex. --property=prop1=foo")
String[] applicationProperties;

@CommandLine.Option(names = { "--logging" }, defaultValue = "false",
description = "Can be used to turn on logging (logs to file in <user home>/.camel directory)")
protected boolean logging;
Expand Down Expand Up @@ -328,6 +332,8 @@ protected Integer runSilently(boolean ignoreLoadingError, boolean lazyBean) thro
run.localKameletDir = localKameletDir;
run.ignoreLoadingError = ignoreLoadingError;
run.lazyBean = lazyBean;
run.property = applicationProperties;

return run.runExport(ignoreLoadingError);
}

Expand Down Expand Up @@ -699,6 +705,10 @@ protected void copySettingsAndProfile(
customize.apply(prop2);
}

// User properties
Properties prop3 = new CamelCaseOrderedProperties();
prepareUserProperties(prop3);

FileOutputStream fos = new FileOutputStream(new File(targetDir, "application.properties"), false);
try {
for (Map.Entry<Object, Object> entry : prop2.entrySet()) {
Expand Down Expand Up @@ -727,14 +737,37 @@ protected void copySettingsAndProfile(
fos.write("\n".getBytes(StandardCharsets.UTF_8));
}
}
for (Map.Entry<Object, Object> entryUserProp : prop3.entrySet()) {
String uK = entryUserProp.getKey().toString();
String uV = entryUserProp.getValue().toString();
String line = applicationPropertyLine(uK, uV);
if (line != null && !line.isBlank()) {
fos.write(line.getBytes(StandardCharsets.UTF_8));
fos.write("\n".getBytes(StandardCharsets.UTF_8));
}
}
}
} finally {
IOHelper.close(fos);
}
}

protected void prepareApplicationProperties(Properties properties) {
// noop
// NOOP
}

protected void prepareUserProperties(Properties properties) {
if (this.applicationProperties != null) {
for (String s : this.applicationProperties) {
String[] kv = s.split("=");
if (kv.length != 2) {
// likely a user mistake, we warn the user
printer().println("WARN: property '" + s + "'' has a bad format (should be 'key=value'), skipping.");
} else {
properties.put(kv[0], kv[1]);
}
}
}
}

// Returns true if it has either an openapi spec or it uses contract-first DSL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ public Integer export() throws Exception {

@Override
protected void prepareApplicationProperties(Properties properties) {
super.prepareApplicationProperties(properties);
// quarkus native compilation only works if we specify each resource explicit

StringJoiner sj = new StringJoiner(",");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,7 @@ protected int runQuarkus() throws Exception {
eq.loggingLevel = "off";
eq.ignoreLoadingError = this.ignoreLoadingError;
eq.lazyBean = this.lazyBean;
eq.applicationProperties = this.property;

printer().println("Running using Quarkus v" + eq.quarkusVersion + " (preparing and downloading files)");

Expand Down Expand Up @@ -1026,6 +1027,7 @@ protected int runSpringBoot() throws Exception {
eq.loggingLevel = "off";
eq.ignoreLoadingError = this.ignoreLoadingError;
eq.lazyBean = this.lazyBean;
eq.applicationProperties = this.property;

printer().println("Running using Spring Boot v" + eq.springBootVersion + " (preparing and downloading files)");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

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

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.Properties;
import java.util.stream.Stream;

import org.apache.camel.dsl.jbang.core.common.RuntimeType;
import org.apache.camel.util.FileUtil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import picocli.CommandLine;

class ExportMainApplicationProperties {

private File workingDir;
private File profile = new File(".", "application.properties");

@BeforeEach
public void setup() throws IOException {
Path base = Paths.get("target");
workingDir = Files.createTempDirectory(base, "camel-export").toFile();
}

@AfterEach
public void end() throws IOException {
// force removing, since deleteOnExit is not removing.
FileUtil.removeDir(workingDir);
FileUtil.deleteFile(profile);
}

private static Stream<Arguments> runtimeProvider() {
return Stream.of(
Arguments.of(RuntimeType.quarkus),
Arguments.of(RuntimeType.springBoot),
Arguments.of(RuntimeType.main));
}

@ParameterizedTest
@MethodSource("runtimeProvider")
public void shouldExportUserPropertyOverride(RuntimeType rt) throws Exception {
// prepare as we need application.properties that contains configuration to be overridden
Files.copy(
new File("src/test/resources/sample-application.properties").toPath(),
profile.toPath(),
StandardCopyOption.REPLACE_EXISTING);

// We need a real file as we want to test the generated content
Export command = createCommand(rt,
new String[] { "src/test/resources/route.yaml", "src/test/resources/sample-application.properties" },
"--gav=examples:route:1.0.0", "--dir=" + workingDir, "--quiet",
"--property", "hello=test");
int exit = command.doCall();

Assertions.assertEquals(0, exit);
// Application properties
File appProperties = new File(workingDir + "/src/main/resources", "application.properties");
Assertions.assertTrue(appProperties.exists(), "Missing application properties");
Properties appProps = new Properties();
appProps.load(new FileInputStream(appProperties));
Assertions.assertEquals("test", appProps.getProperty("hello"));
Assertions.assertEquals("true", appProps.getProperty("another.property"));
}

private Export createCommand(RuntimeType rt, String[] files, String... args) {
Export command = new Export(new CamelJBangMain());
CommandLine.populateCommand(command, "--gav=examples:route:1.0.0", "--dir=" + workingDir, "--quiet",
"--runtime=%s".formatted(rt.runtime()));
if (args != null) {
CommandLine.populateCommand(command, args);
}
command.files = Arrays.asList(files);
return command;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.stream.Stream;

import org.apache.camel.dsl.jbang.core.common.RuntimeType;
Expand Down Expand Up @@ -483,4 +484,24 @@ public void assertApplicationPropertiesContentJava(RuntimeType rt, File appProps
}
}

@ParameterizedTest
@MethodSource("runtimeProvider")
public void shouldExportUserProperty(RuntimeType rt) throws Exception {
// We need a real file as we want to test the generated content
Export command = createCommand(rt, new String[] { "src/test/resources/route.yaml" },
"--gav=examples:route:1.0.0", "--dir=" + workingDir, "--quiet",
"--property", "hello=world");
int exit = command.doCall();

Assertions.assertEquals(0, exit);
// In this test we can validate any generic resource that must be created along the export.
// Exporting once to reduce the time to execute the test and the resource required to test.

// Application properties
File appProperties = new File(workingDir + "/src/main/resources", "application.properties");
Assertions.assertTrue(appProperties.exists(), "Missing application properties");
Properties appProps = new Properties();
appProps.load(new FileInputStream(appProperties));
Assertions.assertEquals("world", appProps.getProperty("hello"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
hello=world
another.property=true
Loading