Skip to content

Commit

Permalink
Merge pull request #44169 from gsmet/3.16.1-backports-2
Browse files Browse the repository at this point in the history
[3.16] 3.16.1 backports 2
  • Loading branch information
gsmet authored Oct 30, 2024
2 parents 133e439 + 607e6f6 commit 81a24d9
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 113 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
<junit.jupiter.version>5.10.5</junit.jupiter.version>
<infinispan.version>15.0.10.Final</infinispan.version>
<infinispan.protostream.version>5.0.12.Final</infinispan.protostream.version>
<caffeine.version>3.1.5</caffeine.version>
<caffeine.version>3.1.8</caffeine.version>
<netty.version>4.1.111.Final</netty.version>
<brotli4j.version>1.16.0</brotli4j.version>
<reactive-streams.version>1.0.4</reactive-streams.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ public interface Capability {
String OPENSHIFT_CLIENT = OPENSHIFT + ".client";

String OIDC = QUARKUS_PREFIX + ".oidc";
String OIDC_CLIENT = OIDC + ".client";

String KEYCLOAK_AUTHORIZATION = QUARKUS_PREFIX + ".keycloak.authorization";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Also, if you use Keycloak and bearer tokens, see the Quarkus xref:security-keycl

To learn about how you can protect service applications by using OIDC Bearer token authentication, see the following tutorial:

* xref:security-oidc-bearer-token-authentication-tutorial.adoc[Protect a web application by using OpenID Connect (OIDC) authorization code flow].
* xref:security-oidc-bearer-token-authentication-tutorial.adoc[Protect a service application by using OpenID Connect (OIDC) Bearer token authentication].

For information about how to support multiple tenants, see the Quarkus xref:security-openid-connect-multitenancy.adoc[Using OpenID Connect Multi-Tenancy] guide.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/web-dependency-locator.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ This means adding the following to your `index.html` will allow you to import we

===== Automatic imports

You can also automate the imports above. To do this, move your web assets from `src/main/resources/META-INF/resources` to `src/main/web`
You can also automate the imports above. To do this, move your web assets from `src/main/resources/META-INF/resources` to `src/main/resources/web`
and now replace the above scripts and imports with `{#bundle /}`:

[source,html]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,10 @@ private DevServicesResultBuildItem.RunningDevService startElasticsearchDevServic
// Starting the server
final Supplier<DevServicesResultBuildItem.RunningDevService> defaultElasticsearchSupplier = () -> {

GenericContainer<?> container = resolvedDistribution.equals(Distribution.ELASTIC)
CreatedContainer createdContainer = resolvedDistribution.equals(Distribution.ELASTIC)
? createElasticsearchContainer(config, resolvedImageName, useSharedNetwork)
: createOpensearchContainer(config, resolvedImageName, useSharedNetwork);
GenericContainer<?> container = createdContainer.genericContainer();

if (config.serviceName != null) {
container.withLabel(DEV_SERVICE_LABEL, config.serviceName);
Expand All @@ -209,11 +210,15 @@ private DevServicesResultBuildItem.RunningDevService startElasticsearchDevServic
container.withReuse(config.reuse);

container.start();

var httpHost = container.getHost() + ":" + container.getMappedPort(ELASTICSEARCH_PORT);
if (createdContainer.hostName() != null) {
httpHost = createdContainer.hostName() + ":" + ELASTICSEARCH_PORT;
}
return new DevServicesResultBuildItem.RunningDevService(Feature.ELASTICSEARCH_REST_CLIENT_COMMON.getName(),
container.getContainerId(),
new ContainerShutdownCloseable(container, "Elasticsearch"),
buildPropertiesMap(buildItemConfig,
container.getHost() + ":" + container.getMappedPort(ELASTICSEARCH_PORT)));
buildPropertiesMap(buildItemConfig, httpHost));
};

return maybeContainerAddress
Expand All @@ -225,12 +230,13 @@ private DevServicesResultBuildItem.RunningDevService startElasticsearchDevServic
.orElseGet(defaultElasticsearchSupplier);
}

private GenericContainer<?> createElasticsearchContainer(ElasticsearchDevServicesBuildTimeConfig config,
private CreatedContainer createElasticsearchContainer(ElasticsearchDevServicesBuildTimeConfig config,
DockerImageName resolvedImageName, boolean useSharedNetwork) {
ElasticsearchContainer container = new ElasticsearchContainer(
resolvedImageName.asCompatibleSubstituteFor("docker.elastic.co/elasticsearch/elasticsearch"));
String hostName = null;
if (useSharedNetwork) {
ConfigureUtil.configureSharedNetwork(container, DEV_SERVICE_ELASTICSEARCH);
hostName = ConfigureUtil.configureSharedNetwork(container, DEV_SERVICE_ELASTICSEARCH);
}

// Disable security as else we would need to configure it correctly to avoid tons of WARNING in the log
Expand All @@ -241,15 +247,17 @@ private GenericContainer<?> createElasticsearchContainer(ElasticsearchDevService
// See https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-cluster.html#disk-based-shard-allocation
container.addEnv("cluster.routing.allocation.disk.threshold_enabled", "false");
container.addEnv("ES_JAVA_OPTS", config.javaOpts);
return container;

return new CreatedContainer(container, hostName);
}

private GenericContainer<?> createOpensearchContainer(ElasticsearchDevServicesBuildTimeConfig config,
private CreatedContainer createOpensearchContainer(ElasticsearchDevServicesBuildTimeConfig config,
DockerImageName resolvedImageName, boolean useSharedNetwork) {
OpensearchContainer container = new OpensearchContainer(
resolvedImageName.asCompatibleSubstituteFor("opensearchproject/opensearch"));
String hostName = null;
if (useSharedNetwork) {
ConfigureUtil.configureSharedNetwork(container, DEV_SERVICE_OPENSEARCH);
hostName = ConfigureUtil.configureSharedNetwork(container, DEV_SERVICE_OPENSEARCH);
}

container.addEnv("bootstrap.memory_lock", "true");
Expand All @@ -264,7 +272,11 @@ private GenericContainer<?> createOpensearchContainer(ElasticsearchDevServicesBu
// Considering dev services are transient and not intended for production by nature,
// we'll just set some hardcoded password.
container.addEnv("OPENSEARCH_INITIAL_ADMIN_PASSWORD", "NotActua11y$trongPa$$word");
return container;

return new CreatedContainer(container, hostName);
}

private record CreatedContainer(GenericContainer<?> genericContainer, String hostName) {
}

private DockerImageName resolveImageName(ElasticsearchDevServicesBuildTimeConfig config,
Expand Down
5 changes: 5 additions & 0 deletions extensions/oidc-client/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-maven-plugin</artifactId>
<configuration>
<capabilities>
<provides>io.quarkus.oidc.client</provides>
</capabilities>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -30,10 +29,10 @@
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
import io.quarkus.maven.dependency.ArtifactKey;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.quarkus.vertx.http.deployment.spi.GeneratedStaticResourceBuildItem;
import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig;
import io.quarkus.webdependency.locator.runtime.WebDependencyLocatorRecorder;
import io.vertx.core.Handler;
Expand All @@ -43,96 +42,81 @@ public class WebDependencyLocatorProcessor {
private static final Logger log = Logger.getLogger(WebDependencyLocatorProcessor.class.getName());

@BuildStep
public void findRelevantFiles(BuildProducer<FeatureBuildItem> feature,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedProducer,
WebDependencyLocatorConfig config,
OutputTargetBuildItem outputTarget) throws IOException {

Path web = outputTarget.getOutputDirectory().getParent()
.resolve(SRC)
.resolve(MAIN)
.resolve(RESOURCES)
.resolve(config.webRoot);

if (Files.exists(web)) {
hotDeploymentWatchedProducer.produce(new HotDeploymentWatchedFileBuildItem(config.webRoot + SLASH + STAR + STAR));
// Find all css and js (under /app)
Path app = web
.resolve(config.appRoot);
public void feature(BuildProducer<FeatureBuildItem> feature) {
feature.produce(new FeatureBuildItem(Feature.WEB_DEPENDENCY_LOCATOR));
}

List<Path> cssFiles = new ArrayList<>();
List<Path> jsFiles = new ArrayList<>();
@BuildStep
public void findRelevantFiles(BuildProducer<GeneratedStaticResourceBuildItem> generatedStaticProducer,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedProducer,
WebDependencyLocatorConfig config) throws IOException {

if (Files.exists(app)) {
QuarkusClassLoader.visitRuntimeResources(config.webRoot, visit -> {
final Path web = visit.getPath();
if (Files.isDirectory(web)) {
hotDeploymentWatchedProducer
.produce(new HotDeploymentWatchedFileBuildItem(
config.webRoot + SLASH + config.appRoot + SLASH + STAR + STAR));
try (Stream<Path> appstream = Files.walk(app)) {
appstream.forEach(path -> {
if (Files.isRegularFile(path) && path.toString().endsWith(DOT_CSS)) {
cssFiles.add(web.relativize(path));
} else if (Files.isRegularFile(path) && path.toString().endsWith(DOT_JS)) {
jsFiles.add(web.relativize(path));
.produce(new HotDeploymentWatchedFileBuildItem(config.webRoot + SLASH + STAR + STAR));
// Find all css and js (under /app)
Path app = web
.resolve(config.appRoot);

List<Path> cssFiles = new ArrayList<>();
List<Path> jsFiles = new ArrayList<>();

if (Files.exists(app)) {
hotDeploymentWatchedProducer
.produce(new HotDeploymentWatchedFileBuildItem(
config.webRoot + SLASH + config.appRoot + SLASH + STAR + STAR));
try (Stream<Path> appstream = Files.walk(app)) {
appstream.forEach(path -> {
if (Files.isRegularFile(path) && path.toString().endsWith(DOT_CSS)) {
cssFiles.add(web.relativize(path));
} else if (Files.isRegularFile(path) && path.toString().endsWith(DOT_JS)) {
jsFiles.add(web.relativize(path));
}
});
} catch (IOException e) {
throw new RuntimeException(e);
}
}

try (Stream<Path> webstream = Files.walk(web)) {

webstream.forEach(path -> {
if (Files.isRegularFile(path)) {
String endpoint = SLASH + web.relativize(path);
try {
if (path.toString().endsWith(DOT_HTML)) {
generatedStaticProducer.produce(new GeneratedStaticResourceBuildItem(endpoint,
processHtml(path, cssFiles, jsFiles)));
} else {
generatedStaticProducer.produce(new GeneratedStaticResourceBuildItem(endpoint, path));
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
});
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
});

try (Stream<Path> webstream = Files.walk(web)) {

final Path resourcesDirectory = outputTarget.getOutputDirectory()
.resolve(CLASSES)
.resolve(META_INF)
.resolve(RESOURCES);
Files.createDirectories(resourcesDirectory);

webstream.forEach(path -> {
if (Files.isRegularFile(path)) {
try {
copyResource(resourcesDirectory, web, path, cssFiles, jsFiles, path.toString().endsWith(DOT_HTML));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
} else if (Files.isRegularFile(path)) {

}
});
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
feature.produce(new FeatureBuildItem(Feature.WEB_DEPENDENCY_LOCATOR));
}

private void copyResource(Path resourcesDirectory, Path webRoot, Path path, List<Path> cssFiles, List<Path> jsFiles,
boolean filter)
private byte[] processHtml(
Path path, List<Path> cssFiles, List<Path> jsFiles)
throws IOException {
try {
StringJoiner modifiedContent = new StringJoiner(System.lineSeparator());

Path relativizePath = webRoot.relativize(path);
Files.lines(path).forEach(line -> {
String modifiedLine = processLine(line, cssFiles, jsFiles);
modifiedContent.add(modifiedLine);
});

byte[] toBeCopied;
if (filter) {
StringJoiner modifiedContent = new StringJoiner(System.lineSeparator());

Files.lines(path).forEach(line -> {
String modifiedLine = processLine(line, cssFiles, jsFiles);
modifiedContent.add(modifiedLine);
});

String result = modifiedContent.toString();
toBeCopied = result.getBytes();
} else {
toBeCopied = Files.readAllBytes(path);
}

final Path resourceFile = resourcesDirectory.resolve(relativizePath);
Files.createDirectories(resourceFile.getParent());
Files.write(resourceFile, toBeCopied, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);

} catch (IOException e) {
throw new UncheckedIOException(e);
}
String result = modifiedContent.toString();
return result.getBytes();
}

private static String processLine(String line, List<Path> cssFiles, List<Path> jsFiles) {
Expand Down Expand Up @@ -310,13 +294,6 @@ static class LibInfo {
private static final String TAB = "\t";
private static final String TAB2 = TAB + TAB;

private static final String CLASSES = "classes";
private static final String META_INF = "META-INF";
private static final String RESOURCES = "resources";

private static final String SRC = "src";
private static final String MAIN = "main";

private static final String SLASH = "/";
private static final String STAR = "*";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Consumer;

import org.jboss.logging.Logger;

import io.quarkus.commons.classloading.ClassLoaderHelper;
import io.quarkus.paths.ManifestAttributes;
import io.quarkus.paths.PathVisit;

/**
* The ClassLoader used for non production Quarkus applications (i.e. dev and test mode).
Expand All @@ -48,14 +50,42 @@ public class QuarkusClassLoader extends ClassLoader implements Closeable {
registerAsParallelCapable();
}

private static RuntimeException nonQuarkusClassLoaderError() {
return new IllegalStateException("The current classloader is not an instance of "
+ QuarkusClassLoader.class.getName() + " but "
+ Thread.currentThread().getContextClassLoader().getClass().getName());
}

/**
* Visits every found runtime resource with a given name. If a resource is not found, the visitor will
* simply not be called.
* <p>
* IMPORTANT: this method works only when the current class loader is an instance of {@link QuarkusClassLoader},
* otherwise it throws an error with the corresponding message.
*
* @param resourceName runtime resource name to visit
* @param visitor runtime resource visitor
*/
public static void visitRuntimeResources(String resourceName, Consumer<PathVisit> visitor) {
if (Thread.currentThread().getContextClassLoader() instanceof QuarkusClassLoader classLoader) {
for (var element : classLoader.getElementsWithResource(resourceName)) {
if (element.isRuntime()) {
element.apply(tree -> {
tree.accept(resourceName, visitor);
return null;
});
}
}
} else {
throw nonQuarkusClassLoaderError();
}
}

public static List<ClassPathElement> getElements(String resourceName, boolean onlyFromCurrentClassLoader) {
if (Thread.currentThread().getContextClassLoader() instanceof QuarkusClassLoader classLoader) {
return classLoader.getElementsWithResource(resourceName, onlyFromCurrentClassLoader);
}

throw new IllegalStateException("The current classloader is not an instance of "
+ QuarkusClassLoader.class.getName() + " but "
+ Thread.currentThread().getContextClassLoader().getClass().getName());
throw nonQuarkusClassLoaderError();
}

/**
Expand All @@ -78,10 +108,7 @@ public static boolean isApplicationClass(String className) {

return classPathResourceIndex.getFirstClassPathElement(resourceName) != null;
}

throw new IllegalStateException("The current classloader is not an instance of "
+ QuarkusClassLoader.class.getName() + " but "
+ Thread.currentThread().getContextClassLoader().getClass().getName());
throw nonQuarkusClassLoaderError();
}

/**
Expand Down
Loading

0 comments on commit 81a24d9

Please sign in to comment.