Skip to content

Commit

Permalink
Merge branch 'main' into 31210
Browse files Browse the repository at this point in the history
  • Loading branch information
bakrhaso authored Feb 27, 2023
2 parents 49a1b79 + 859c915 commit f68a742
Show file tree
Hide file tree
Showing 60 changed files with 318 additions and 210 deletions.
6 changes: 3 additions & 3 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
<okhttp.version>3.14.9</okhttp.version><!-- keep in sync with okio -->
<okio.version>1.17.2</okio.version><!-- keep in sync with okhttp -->
<hibernate-quarkus-local-cache.version>0.2.0</hibernate-quarkus-local-cache.version>
<flapdoodle.mongo.version>4.5.1</flapdoodle.mongo.version>
<flapdoodle.mongo.version>4.6.1</flapdoodle.mongo.version>
<quarkus-spring-api.version>5.2.SP7</quarkus-spring-api.version>
<quarkus-spring-data-api.version>2.1.SP2</quarkus-spring-data-api.version>
<quarkus-spring-security-api.version>5.4.Final</quarkus-spring-security-api.version>
Expand All @@ -191,7 +191,7 @@
<checker-qual.version>3.31.0</checker-qual.version>
<error-prone-annotations.version>2.18.0</error-prone-annotations.version>
<jib-core.version>0.23.0</jib-core.version>
<google-http-client.version>1.42.3</google-http-client.version>
<google-http-client.version>1.43.0</google-http-client.version>
<scram-client.version>2.1</scram-client.version>
<picocli.version>4.7.1</picocli.version>
<google-cloud-functions.version>1.0.4</google-cloud-functions.version>
Expand All @@ -211,7 +211,7 @@
<aesh.version>2.7</aesh.version>
<!-- these two artifacts needs to be compatible together -->
<strimzi-oauth.version>0.11.0</strimzi-oauth.version>
<strimzi-oauth.nimbus.version>9.30.2</strimzi-oauth.nimbus.version>
<strimzi-oauth.nimbus.version>9.31</strimzi-oauth.nimbus.version>
<java-buildpack-client.version>0.0.6</java-buildpack-client.version>
<org-crac.version>0.1.3</org-crac.version>
<sshd-common.version>2.9.2</sshd-common.version>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.quarkus.deployment.dev;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* Lock that is used to prevent scanning and compiling while code generator is updating sources
* There is a race when testing this, where you can see the intermediate empty state of the
* file, or where the file time changes twice. Codegen hold this lock during modification
* to avoid the race.
*/
public class CodeGenLock {

/**
* Allow for multiple code generators to run at the same time but give exclusive run to RuntimeUpdatesProcessor
*/
private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);

public static Lock lockForCodeGen() {
return lock.readLock();
}

public static Lock lockForCompilation() {
return lock.writeLock();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.locks.Lock;

import org.eclipse.microprofile.config.Config;
import org.jboss.logging.Logger;
Expand All @@ -22,6 +23,7 @@ class CodeGenWatcher {

private final QuarkusClassLoader deploymentClassLoader;
private final FSWatchUtil fsWatchUtil;
private final Lock codeGenLock = CodeGenLock.lockForCodeGen();

CodeGenWatcher(CuratedApplication curatedApplication, DevModeContext context) throws CodeGenException {
final QuarkusClassLoader deploymentClassLoader = curatedApplication.createDeploymentClassLoader();
Expand All @@ -39,12 +41,15 @@ class CodeGenWatcher {
for (CodeGenData codeGen : codeGens) {
watchers.add(new FSWatchUtil.Watcher(codeGen.sourceDir, codeGen.provider.inputExtension(),
modifiedPaths -> {
codeGenLock.lock();
try {
CodeGenerator.trigger(deploymentClassLoader,
codeGen,
curatedApplication.getApplicationModel(), config, false);
} catch (Exception any) {
log.warn("Code generation failed", any);
} finally {
codeGenLock.unlock();
}
}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
Expand Down Expand Up @@ -107,6 +108,7 @@ public class RuntimeUpdatesProcessor implements HotReplacementContext, Closeable
private final BiConsumer<DevModeContext.ModuleInfo, String> copyResourceNotification;
private final BiFunction<String, byte[], byte[]> classTransformers;
private final ReentrantLock scanLock = new ReentrantLock();
private final Lock codeGenLock = CodeGenLock.lockForCompilation();

/**
* The index for the last successful start. Used to determine if the class has changed its structure
Expand Down Expand Up @@ -442,6 +444,8 @@ public boolean doScan(boolean userInitiated, boolean forceRestart) {
return false;
}
scanLock.lock();
codeGenLock.lock();

try {
final long startNanoseconds = System.nanoTime();
for (Runnable step : preScanSteps) {
Expand Down Expand Up @@ -564,6 +568,7 @@ public boolean doScan(boolean userInitiated, boolean forceRestart) {

} finally {
scanLock.unlock();
codeGenLock.unlock();
}
}

Expand Down
11 changes: 8 additions & 3 deletions docs/src/main/asciidoc/kubernetes-client.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ Note that the full list of properties is available in the link:#quarkus-kubernet

In dev mode and when running tests, xref:kubernetes-dev-services.adoc[Dev Services for Kubernetes] automatically starts a Kubernetes API server.

=== Overriding
=== Customizing and overriding

The extension also allows application code to override either of `io.fabric8.kubernetes.client.Config` or `io.fabric8.kubernetes.client.KubernetesClient` which are
normally provided by the extension by simply declaring custom versions of those beans.
Quarkus provides multiple integration points for influencing the Kubernetes Client provided as a CDI bean.

The first integration point is the use of the `io.quarkus.kubernetes.client.KubernetesConfigCustomizer` interface. When such a bean exists,
it allows for arbitrary customizations of the `io.fabric8.kubernetes.client.Config` created by Quarkus (which takes into account the `quarkus.kubernetes-client.*` properties).

Alternatively, application code can override the `io.fabric8.kubernetes.client.Config` or even the `io.fabric8.kubernetes.client.KubernetesClient` bean (which are
normally provided by the extension) by simply declaring custom versions of those beans.

An example of this can be seen in the following snippet:

Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/qute-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ And must be used in a form of `{item_hasNext}` inside a `{#for}` section with th
{#for item in items}
{item_count}. {item.name} <1>
{#if item_hasNext}<br>{/if} <2>
{/each}
{/for}
----
<1> `item_count` represents one-based index.
<2> `<br>` is only rendered if the iteration has more elements.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ private boolean possiblyBeanArchive(ApplicationArchive archive) {
|| text.contains("bean-discovery-mode=\"all\"")) {
LOGGER.warnf("Detected bean archive with bean discovery mode of 'all', "
+ "this is not portable in CDI Lite and is treated as 'annotated' in Quarkus! "
+ "Path to beans.xml: %s", pathVisit.getPath());
+ "Path to beans.xml: %s",
archive.getKey() != null ? archive.getKey().toGacString() + ":" + pathVisit.getPath()
: pathVisit.getPath());
}
} catch (IOException e) {
throw new UncheckedIOException(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
package io.quarkus.grpc.deployment;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Consumer;

import org.jboss.logging.Logger;

Expand Down Expand Up @@ -72,7 +65,6 @@ private boolean isEnabled(CodeGenContext context, String name, boolean def) {

public void postprocess() {
SourceRoot sr = new SourceRoot(root);
Map<Path, Path> changedFiles = new HashMap<Path, Path>();
try {
sr.parse("", new SourceRoot.Callback() {
@Override
Expand All @@ -84,19 +76,9 @@ public com.github.javaparser.utils.SourceRoot.Callback.Result process(Path local
if (unit.getPrimaryType().isPresent()) {
TypeDeclaration<?> type = unit.getPrimaryType().get();
postprocess(unit, type);

// save to a temporary file first, then move all temporary unit files at the same time
try {
unit.setStorage(Files.createTempFile(null, null),
sr.getParserConfiguration().getCharacterEncoding())
.getStorage().get().save(sr.getPrinter());
} catch (IOException ex) {
throw new RuntimeException(ex);
}

changedFiles.put(unit.getStorage().get().getPath(), absolutePath);
return Result.DONT_SAVE;
return Result.SAVE;
}

} else {
// Compilation issue - report and skip
log.errorf(
Expand All @@ -108,33 +90,9 @@ public com.github.javaparser.utils.SourceRoot.Callback.Result process(Path local
return Result.DONT_SAVE;
}
});

changedFiles.entrySet().forEach(new Consumer<Entry<Path, Path>>() {
@Override
public void accept(Entry<Path, Path> entry) {
try {
Files.move(entry.getKey(), entry.getValue(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
});
changedFiles.clear();

} catch (Exception e) {
// read issue, report and exit
log.error("Unable to parse the classes generated using protoc - skipping gRPC post processing", e);
} finally {
changedFiles.entrySet().forEach(new Consumer<Entry<Path, Path>>() {
@Override
public void accept(Entry<Path, Path> e) {
try {
Files.deleteIfExists(e.getKey());
} catch (IOException discard) {
// Ignore it.
}
}
});
}
}

Expand Down
5 changes: 5 additions & 0 deletions extensions/kubernetes-client/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.quarkus.kubernetes.client.deployment;

import static org.junit.jupiter.api.Assertions.assertEquals;

import jakarta.inject.Inject;
import jakarta.inject.Singleton;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.quarkus.kubernetes.client.KubernetesConfigCustomizer;
import io.quarkus.test.QuarkusUnitTest;

public class KubernetesClientCDITest {

@Inject
KubernetesClient client;

@Test
public void test() {
assertEquals("-1", client.getConfiguration().getApiVersion());
}

@RegisterExtension
static QuarkusUnitTest runner = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(Customizer.class))
.overrideConfigKey("quarkus.kubernetes-client.devservices.enabled", "false");

@Singleton
public static class Customizer implements KubernetesConfigCustomizer {
@Override
public void customize(Config config) {
config.setApiVersion("-1");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.quarkus.kubernetes.client;

import java.util.List;

import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.quarkus.kubernetes.client.runtime.KubernetesClientBuildConfig;
import io.quarkus.kubernetes.client.runtime.KubernetesClientProducer;
import io.quarkus.kubernetes.client.runtime.KubernetesConfigProducer;
import io.quarkus.runtime.TlsConfig;

/**
* Meant to be implemented by a CDI bean that provided arbitrary customization for the default {@link Config} created by
* Quarkus.
* <p>
* The {@link Config} is in turn used to produce the default {@link KubernetesClient}
* <p>
*
* @see KubernetesConfigProducer#config(KubernetesClientBuildConfig, TlsConfig, List) }
* @see KubernetesClientProducer#kubernetesClient(Config) }
*/
public interface KubernetesConfigCustomizer {

void customize(Config config);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package io.quarkus.kubernetes.client.runtime;

import java.util.List;

import jakarta.enterprise.inject.Produces;
import jakarta.inject.Singleton;

import io.fabric8.kubernetes.client.Config;
import io.quarkus.arc.All;
import io.quarkus.arc.DefaultBean;
import io.quarkus.kubernetes.client.KubernetesConfigCustomizer;
import io.quarkus.runtime.TlsConfig;

@Singleton
Expand All @@ -13,7 +17,13 @@ public class KubernetesConfigProducer {
@DefaultBean
@Singleton
@Produces
public Config config(KubernetesClientBuildConfig buildConfig, TlsConfig tlsConfig) {
return KubernetesClientUtils.createConfig(buildConfig, tlsConfig);
public Config config(KubernetesClientBuildConfig buildConfig,
TlsConfig tlsConfig,
@All List<KubernetesConfigCustomizer> customizers) {
var result = KubernetesClientUtils.createConfig(buildConfig, tlsConfig);
for (KubernetesConfigCustomizer customizer : customizers) {
customizer.customize(result);
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io.quarkus.runtime.ShutdownContext;
import io.quarkus.runtime.annotations.Recorder;
import io.quarkus.security.AuthenticationCompletionException;
import io.quarkus.security.AuthenticationException;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.AuthenticationRedirectException;
import io.quarkus.security.ForbiddenException;
Expand Down Expand Up @@ -126,9 +127,7 @@ public void handle(RoutingContext request) {
}
}

if (request.failure() instanceof AuthenticationFailedException
|| request.failure() instanceof AuthenticationCompletionException
|| request.failure() instanceof AuthenticationRedirectException
if (request.failure() instanceof AuthenticationException
|| request.failure() instanceof ForbiddenException) {
super.handle(request);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* then we need to make sure that Arc doesn't create a bean for it automatically (as it will fail validation because
* there is no way to pass the parameter).
* For these resources we add {@link jakarta.enterprise.inject.Vetoed}, and we generate custom CDI producers under the hood
* in {@link CustomResourceProducersGenerator#generate}.
* in {@code io.quarkus.resteasy.reactive.server.deployment.CustomResourceProducersGenerator#generate}.
*/
public class VetoingAnnotationTransformer implements AnnotationsTransformer {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public interface JaxRsSecurityConfig {
* If no security annotations are affecting a method then they will default to requiring these roles,
* (equivalent to adding an @RolesAllowed annotation with the roles to every endpoint class).
*
* The role of '**' means any authenticated user, which is equivalent to the {@link io.quarkus.security.Authenticated}
* The role of '**' means any authenticated user, which is equivalent to the {@code io.quarkus.security.Authenticated}
* annotation.
*/
Optional<List<String>> defaultRolesAllowed();
Expand Down
Loading

0 comments on commit f68a742

Please sign in to comment.