Skip to content

Commit

Permalink
Implement output-name/add-runner-suffix on Gradle
Browse files Browse the repository at this point in the history
  • Loading branch information
alesj authored and jacobdotcosta committed Jan 10, 2023
1 parent 06b1308 commit 29d8554
Show file tree
Hide file tree
Showing 46 changed files with 1,868 additions and 243 deletions.
97 changes: 97 additions & 0 deletions .github/workflows/ci-istio.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Quarkus CI - Istio

on:
workflow_dispatch:
schedule:
# 2am every weekday + saturday
- cron: '0 2 * * 1-6'

env:
MAVEN_ARGS: -B -e

jobs:
cache:
name: Build and save artifacts
runs-on: ubuntu-latest
if: "github.repository == 'quarkusio/quarkus' || github.event_name == 'workflow_dispatch'"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Install artifacts
run: ./mvnw ${MAVEN_ARGS} -DskipTests -DskipITs -Dinvoker.skip clean install -pl :quarkus-integration-test-istio-invoker -am
- name: Tar Maven repository
shell: bash
run: tar -I 'pigz -9' -cf maven-repo.tgz -C ~ .m2/repository
- name: Persist Maven repository
uses: actions/upload-artifact@v3
with:
name: maven-repo
path: maven-repo.tgz
retention-days: 1

kubernetes:
name: Istio + Kubernetes Integration Tests
needs: cache
runs-on: ubuntu-latest
if: "github.repository == 'quarkusio/quarkus' || github.event_name == 'workflow_dispatch'"
strategy:
fail-fast: false
matrix:
kubernetes: [v1.20.1]
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Download Maven repository
uses: actions/download-artifact@v3
with:
name: maven-repo
path: .
- name: Extract Maven repository
shell: bash
run: tar -xzf maven-repo.tgz -C ~
- name: Set up Minikube-Kubernetes
uses: manusa/[email protected]
with:
minikube version: v1.16.0
kubernetes version: ${{ matrix.kubernetes }}
github token: ${{ secrets.GITHUB_TOKEN }}
start args: '--addons=metrics-server --force'
- name: Quay login
uses: docker/login-action@v2
with:
registry: quay.io
username: ${{ secrets.QUAY_QUARKUSCI_USERNAME }}
password: ${{ secrets.QUAY_QUARKUSCI_PASSWORD }}
- name: Get kubeconfig
id: kubeconfig
run: a="$(cat ~/.kube/config)"; a="${a//'%'/'%25'}"; a="${a//$'\n'/'%0A'}"; a="${a//$'\r'/'%0D'}"; echo "::set-output name=config::$a"
- name: Install Istio
uses: huang195/[email protected]
with:
kubeconfig: "${{steps.kubeconfig.outputs.config}}"
istio version: '1.15.2'
- name: Run Istio Invoker Tests
run: |
export QUARKUS_CONTAINER_IMAGE_GROUP=quarkustesting
export QUARKUS_CONTAINER_IMAGE_TAG=${{ github.sha }}
export QUARKUS_CONTAINER_IMAGE_REGISTRY=quay.io
./mvnw ${MAVEN_ARGS} clean install -pl :quarkus-integration-test-istio-invoker -De2e-tests -Dkubernetes-e2e-tests
- name: Report status
if: "always() && github.repository == 'quarkusio/quarkus'"
shell: bash
run: |
curl -Ls https://sh.jbang.dev | bash -s - app setup
~/.jbang/bin/jbang .github/NativeBuildReport.java \
issueNumber=29536 \
runId=${{ github.run_id }} \
status=${{ job.status }} \
token=${{ secrets.GITHUB_API_TOKEN }} \
issueRepo=${{ github.repository }} \
thisRepo=${{ github.repository }}
7 changes: 6 additions & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@
<docker-java.version>3.2.13</docker-java.version> <!-- must be the version Testcontainers use -->
<com.dajudge.kindcontainer>1.3.0</com.dajudge.kindcontainer>
<aesh-readline.version>2.2</aesh-readline.version>
<aesh.version>2.6</aesh.version>
<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.27</strimzi-oauth.nimbus.version>
Expand Down Expand Up @@ -1909,6 +1909,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-grpc-xds</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-grpc-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.cli.image;

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

import java.io.File;
Expand Down Expand Up @@ -94,6 +95,10 @@ public void testUsage() throws Exception {
// 1 image --dry-run
result = CliDriver.execute(project, "image", "--dry-run");
assertEquals(CommandLine.ExitCode.OK, result.getExitCode(), "Expected OK return code." + result);
assertFalse(result.getStdout().contains("-Dquarkus.package.type=native"));
result = CliDriver.execute(project, "image", "--native", "--dry-run");
assertEquals(CommandLine.ExitCode.OK, result.getExitCode(), "Expected OK return code." + result);
assertTrue(result.getStdout().contains("-Dquarkus.package.type=native"));

// 2 image build --dry-run
result = CliDriver.execute(project, "image", "build", "--dry-run");
Expand Down Expand Up @@ -121,11 +126,13 @@ public void testUsage() throws Exception {
assertTrue(result.getStdout().contains("--builder=openshift"));
assertTrue(result.getStdout().contains("--init-script="));

result = CliDriver.execute(project, "image", "build", "--group=mygroup", "--name=myname", "--tag=1.0", "--dry-run");
result = CliDriver.execute(project, "image", "build", "--group=mygroup", "--name=myname", "--tag=1.0", "--native",
"--dry-run");
assertEquals(CommandLine.ExitCode.OK, result.getExitCode(), "Expected OK return code." + result);
assertTrue(result.getStdout().contains("-Dquarkus.container-image.group=mygroup"));
assertTrue(result.getStdout().contains("-Dquarkus.container-image.name=myname"));
assertTrue(result.getStdout().contains("-Dquarkus.container-image.tag=1.0"));
assertTrue(result.getStdout().contains("-Dquarkus.package.type=native"));

// 3 image push --dry-run
result = CliDriver.execute(project, "image", "push", "--dry-run");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.cli.image;

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

import java.nio.file.Path;
Expand Down Expand Up @@ -47,14 +48,21 @@ public void testUsage() throws Exception {
// 1 image --dry-run
result = CliDriver.execute(project, "image", "--dry-run");
assertEquals(CommandLine.ExitCode.OK, result.getExitCode(), "Expected OK return code." + result);
assertTrue(result.getStdout().contains("quarkus:image-build"));
assertFalse(result.getStdout().contains("-Dnative"));
result = CliDriver.execute(project, "image", "--native", "--dry-run");
assertTrue(result.getStdout().contains("-Dnative"));

// 2 image build --dry-run
result = CliDriver.execute(project, "image", "build", "--dry-run");
assertEquals(CommandLine.ExitCode.OK, result.getExitCode(), "Expected OK return code." + result);
result = CliDriver.execute(project, "image", "build", "--group=mygroup", "--name=myname", "--tag=1.0", "--dry-run");
result = CliDriver.execute(project, "image", "build", "--group=mygroup", "--name=myname", "--tag=1.0", "--native",
"--dry-run");
assertEquals(CommandLine.ExitCode.OK, result.getExitCode(), "Expected OK return code." + result);
assertTrue(result.getStdout().contains("-Dquarkus.container-image.group=mygroup"));
assertTrue(result.getStdout().contains("-Dquarkus.container-image.name=myname"));
assertTrue(result.getStdout().contains("-Dquarkus.container-image.tag=1.0"));
assertTrue(result.getStdout().contains("-Dnative"));

// 3 image push --dry-run
result = CliDriver.execute(project, "image", "push", "--dry-run");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
package io.quarkus.gradle.extension;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;

import javax.annotation.Nullable;

import io.quarkus.bootstrap.BootstrapConstants;
import io.quarkus.bootstrap.model.ApplicationModel;
import io.quarkus.bootstrap.resolver.AppModelResolver;
import io.quarkus.gradle.AppModelGradleResolver;
import io.quarkus.gradle.tasks.QuarkusGradleUtils;
import io.quarkus.gradle.tooling.ToolingUtils;
import io.quarkus.runtime.LaunchMode;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
Expand All @@ -25,13 +19,18 @@
import org.gradle.api.tasks.testing.Test;
import org.gradle.jvm.tasks.Jar;

import io.quarkus.bootstrap.BootstrapConstants;
import io.quarkus.bootstrap.model.ApplicationModel;
import io.quarkus.bootstrap.resolver.AppModelResolver;
import io.quarkus.gradle.AppModelGradleResolver;
import io.quarkus.gradle.tasks.QuarkusGradleUtils;
import io.quarkus.gradle.tooling.ToolingUtils;
import io.quarkus.runtime.LaunchMode;
import javax.annotation.Nullable;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;

public class QuarkusPluginExtension {
private final Project project;
Expand Down Expand Up @@ -85,7 +84,8 @@ public void beforeTest(Test task) {
task.environment(BootstrapConstants.TEST_TO_MAIN_MAPPINGS, fileList);
project.getLogger().debug("test dir mapping - {}", fileList);

final String nativeRunner = task.getProject().getBuildDir().toPath().resolve(finalName() + "-runner")
final String nativeRunner = task.getProject().getBuildDir().toPath()
.resolve(buildNativeRunnerName(props))
.toAbsolutePath()
.toString();
props.put("native.image.path", nativeRunner);
Expand All @@ -94,6 +94,30 @@ public void beforeTest(Test task) {
}
}

public String buildNativeRunnerName(final Map<String, Object> taskSystemProps) {
Properties properties = new Properties(taskSystemProps.size());
properties.putAll(taskSystemProps);
quarkusBuildProperties.entrySet()
.forEach(buildEntry -> properties.putIfAbsent(buildEntry.getKey(), buildEntry.getValue()));
System.getProperties().entrySet()
.forEach(propEntry -> properties.putIfAbsent(propEntry.getKey(), propEntry.getValue()));
System.getenv().entrySet().forEach(
envEntry -> properties.putIfAbsent(envEntry.getKey(), envEntry.getValue()));
StringBuilder nativeRunnerName = new StringBuilder();

if (properties.containsKey("quarkus.package.output-name")) {
nativeRunnerName.append(properties.get("quarkus.package.output-name"));
} else {
nativeRunnerName.append(finalName());
}
if (!properties.containsKey("quarkus.package.add-runner-suffix")
|| (properties.containsKey("quarkus.package.add-runner-suffix")
&& Boolean.parseBoolean((String) properties.get("quarkus.package.add-runner-suffix")))) {
nativeRunnerName.append("-runner");
}
return nativeRunnerName.toString();
}

public Property<String> getFinalName() {
return finalName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,12 @@ public QuarkusBuild manifest(Action<Manifest> action) {

@OutputFile
public File getRunnerJar() {
return new File(getProject().getBuildDir(), extension().finalName() + "-runner.jar");
return new File(getProject().getBuildDir(), String.format("%s.jar", extension().buildNativeRunnerName(Map.of())));
}

@OutputFile
public File getNativeRunner() {
return new File(getProject().getBuildDir(), extension().finalName() + "-runner");
return new File(getProject().getBuildDir(), extension().buildNativeRunnerName(Map.of()));
}

@OutputDirectory
Expand Down
10 changes: 10 additions & 0 deletions docs/src/main/asciidoc/grpc-getting-started.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,16 @@ quarkus.generate-code.grpc.scan-for-proto=<groupId>:<artifactId>
----
The value of the property may be `none`, which is the default value, or a comma separated list of `groupId:artifactId` coordinates.

== Different gRPC implementations / types

Another thing to take note as well is that Quarkus' gRPC support currently includes 3 different types of gRPC usage:

a. old Vert.x gRPC implementation with a separate gRPC server (default)
b. new Vert.x gRPC implementation on top of the existing HTTP server
c. https://grpc.github.io/grpc/core/md_doc_grpc_xds_features.html[xDS gRPC] wrapper over https://github.com/grpc/grpc-java[grpc-java] with a separate Netty based gRPC server

Further docs explain how to enable and use each of them.

== Implementing a gRPC service

Now that we have the generated classes let's implement our _hello_ service.
Expand Down
45 changes: 45 additions & 0 deletions docs/src/main/asciidoc/grpc-service-consumption.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ The `client-name` is the name set in the `@GrpcClient` or derived from the injec
The following examples uses _hello_ as the client name.
Don't forget to replace it with the name you used in the `@GrpcClient` annotation.

IMPORTANT: When you enable `quarkus.grpc.clients."client-name".use-quarkus-grpc-client`, you are then using the new Vert.x gRPC channel implementation, so not all configuration properties can still be applied. And currently there is no Stork support yet.

IMPORTANT: When you enable `quarkus.grpc.clients."client-name".xds.enabled`, it's the xDS that should handle most of the configuration above.

=== Enabling TLS

To enable TLS, use the following configuration.
Expand Down Expand Up @@ -401,6 +405,47 @@ To disable the gRPC client metrics when `quarkus-micrometer` is used, add the fo
quarkus.micrometer.binder.grpc-client.enabled=false
----

== Custom exception handling

If any of the gRPC services or server interceptors throw an (custom) exception, you can add your own https://github.com/quarkusio/quarkus/extensions/grpc/api/src/main/java/io/quarkus/grpc/ExceptionHandlerProvider.java[ExceptionHandlerProvider]
as a CDI bean in your application, to provide a custom handling of those exceptions.

e.g.

[source, java]
----
@ApplicationScoped
public class HelloExceptionHandlerProvider implements ExceptionHandlerProvider {
@Override
public <ReqT, RespT> ExceptionHandler<ReqT, RespT> createHandler(ServerCall.Listener<ReqT> listener,
ServerCall<ReqT, RespT> serverCall, Metadata metadata) {
return new HelloExceptionHandler<>(listener, serverCall, metadata);
}
@Override
public Throwable transform(Throwable t) {
if (t instanceof HelloException he) {
return new StatusRuntimeException(Status.ABORTED.withDescription(he.getName()));
} else {
return ExceptionHandlerProvider.toStatusException(t, true);
}
}
private static class HelloExceptionHandler<A, B> extends ExceptionHandler<A, B> {
public HelloExceptionHandler(ServerCall.Listener<A> listener, ServerCall<A, B> call, Metadata metadata) {
super(listener, call, metadata);
}
@Override
protected void handleException(Throwable t, ServerCall<A, B> call, Metadata metadata) {
StatusRuntimeException sre = (StatusRuntimeException) ExceptionHandlerProvider.toStatusException(t, true);
Metadata trailers = sre.getTrailers() != null ? sre.getTrailers() : metadata;
call.close(sre.getStatus(), trailers);
}
}
}
----

== Dev Mode

By default, when starting the application in dev mode, a gRPC server is started, even if no services are configured.
Expand Down
6 changes: 6 additions & 0 deletions docs/src/main/asciidoc/grpc-service-implementation.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ If you wish to scale your server, you can set the number of server instances by

include::{generated-dir}/config/quarkus-grpc-config-group-config-grpc-server-configuration.adoc[opts=optional, leveloffset=+1]

IMPORTANT: When you disable `quarkus.grpc.server.use-separate-server`, you are then using the new Vert.x gRPC server implementation
which uses the existing HTTP server. Which means that the server port is now `8080` (or the port configured with `quarkus.http.port`).
Also, most of the other configuration properties are no longer applied, since it's the HTTP server that should already be properly configured.

IMPORTANT: When you enable `quarkus.grpc.server.xds.enabled`, it's the xDS that should handle most of the configuration above.

== Example of Configuration

=== Enabling TLS
Expand Down
Loading

0 comments on commit 29d8554

Please sign in to comment.