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

Allow streaming data in deployment classpath methods in Dev UI #42154

Merged
merged 1 commit into from
Jul 26, 2024
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
8 changes: 5 additions & 3 deletions docs/src/main/asciidoc/dev-ui.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1035,9 +1035,9 @@

https://github.com/phillip-kruger/quarkus-jokes/blob/main/deployment/src/main/resources/dev-ui/qwc-jokes-web-components.js[Example code]

==== JsonRpc against the deployment classpath
=== JsonRpc against the deployment classpath

Check warning on line 1038 in docs/src/main/asciidoc/dev-ui.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'JsonRpc against the deployment classpath'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'JsonRpc against the deployment classpath'.", "location": {"path": "docs/src/main/asciidoc/dev-ui.adoc", "range": {"start": {"line": 1038, "column": 5}}}, "severity": "INFO"}

In certain cases you might need to execute methods and/or get data against the deployment classpath. This also happens over JsonRPC communication, but in this case you do not create a JsonRPC Service in the runtime module,

Check warning on line 1040 in docs/src/main/asciidoc/dev-ui.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'.", "location": {"path": "docs/src/main/asciidoc/dev-ui.adoc", "range": {"start": {"line": 1040, "column": 28}}}, "severity": "INFO"}

Check warning on line 1040 in docs/src/main/asciidoc/dev-ui.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'a or b' or 'a, b, or both' rather than 'and/or' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'a or b' or 'a, b, or both' rather than 'and/or' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/dev-ui.adoc", "range": {"start": {"line": 1040, "column": 52}}}, "severity": "WARNING"}

Check warning on line 1040 in docs/src/main/asciidoc/dev-ui.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer. Raw Output: {"message": "[Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer.", "location": {"path": "docs/src/main/asciidoc/dev-ui.adoc", "range": {"start": {"line": 1040, "column": 102}}}, "severity": "INFO"}
you can just supply the code to be run in a supplier in the deployment module. To do this you will produce a `BuildTimeActionBuildItem`, example:

[source,java]
Expand All @@ -1064,9 +1064,11 @@
----
<1> Return or use a BuildProducer to create a `BuildTimeActionBuildItem`
<2> `BuildTimeActionBuildItem` is automatically scoped with your extension namespace
<3> The method name (that can be called from js in the same way as any json-rpc service) is `generateManifests`
<3> Here we add an action, that is the same as a request-response method. The method name (that can be called from js in the same way as any json-rpc service) is `generateManifests`.

Check warning on line 1067 in docs/src/main/asciidoc/dev-ui.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than ', that'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than ', that'.", "location": {"path": "docs/src/main/asciidoc/dev-ui.adoc", "range": {"start": {"line": 1067, "column": 26}}}, "severity": "INFO"}

Check warning on line 1067 in docs/src/main/asciidoc/dev-ui.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'.", "location": {"path": "docs/src/main/asciidoc/dev-ui.adoc", "range": {"start": {"line": 1067, "column": 45}}}, "severity": "INFO"}

===== Dev UI Log
You can also return a `CompletableFuture`/`CompletionStage` as an action, and if you want to stream data you need to use `addSubscription` (rather than `addAction`) and return a `Flow.Publisher`.

Check warning on line 1069 in docs/src/main/asciidoc/dev-ui.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'.", "location": {"path": "docs/src/main/asciidoc/dev-ui.adoc", "range": {"start": {"line": 1069, "column": 61}}}, "severity": "INFO"}

Check warning on line 1069 in docs/src/main/asciidoc/dev-ui.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'.", "location": {"path": "docs/src/main/asciidoc/dev-ui.adoc", "range": {"start": {"line": 1069, "column": 110}}}, "severity": "INFO"}

=== Dev UI Log

Check warning on line 1071 in docs/src/main/asciidoc/dev-ui.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'Dev UI Log'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'Dev UI Log'.", "location": {"path": "docs/src/main/asciidoc/dev-ui.adoc", "range": {"start": {"line": 1071, "column": 5}}}, "severity": "INFO"}

When running a local application using the `999-SNAPSHOT` version, the Dev UI will show a `Dev UI` Log in the footer. This is useful for debugging all JSON RPC messages flowing between the browser and the Quarkus app.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,16 +207,22 @@ DeploymentMethodBuildItem mapDeploymentMethods(
CurateOutcomeBuildItem curateOutcomeBuildItem) {

List<String> methodNames = new ArrayList<>();
List<String> subscriptionNames = new ArrayList<>();
for (BuildTimeActionBuildItem actions : buildTimeActions) {
String extensionPathName = actions.getExtensionPathName(curateOutcomeBuildItem);
for (BuildTimeAction bta : actions.getActions()) {
String fullName = extensionPathName + "." + bta.getMethodName();
DevConsoleManager.register(fullName, bta.getAction());
methodNames.add(fullName);
}
for (BuildTimeAction bts : actions.getSubscriptions()) {
String fullName = extensionPathName + "." + bts.getMethodName();
DevConsoleManager.register(fullName, bts.getAction());
subscriptionNames.add(fullName);
}
}

return new DeploymentMethodBuildItem(methodNames);
return new DeploymentMethodBuildItem(methodNames, subscriptionNames);
}

private Map<String, Object> getBuildTimeDataForPage(AbstractPageBuildItem pageBuildItem) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
public final class DeploymentMethodBuildItem extends SimpleBuildItem {

private final List<String> methods;
private final List<String> subscriptions;

public DeploymentMethodBuildItem(List<String> methods) {
public DeploymentMethodBuildItem(List<String> methods, List<String> subscriptions) {
this.methods = methods;
this.subscriptions = subscriptions;
}

public List<String> getMethods() {
Expand All @@ -22,4 +24,12 @@ public List<String> getMethods() {
public boolean hasMethods() {
return this.methods != null && !this.methods.isEmpty();
}

public List<String> getSubscriptions() {
return this.subscriptions;
}

public boolean hasSubscriptions() {
return this.subscriptions != null && !this.subscriptions.isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@ void findAllJsonRPCMethods(BuildProducer<JsonRPCRuntimeMethodsBuildItem> jsonRPC
requestResponseMethods.addAll(deploymentMethodBuildItem.getMethods());
}

if (deploymentMethodBuildItem.hasSubscriptions()) {
subscriptionMethods.addAll(deploymentMethodBuildItem.getSubscriptions());
}

if (!extensionMethodsMap.isEmpty()) {
jsonRPCMethodsProvider.produce(new JsonRPCRuntimeMethodsBuildItem(extensionMethodsMap));
}
Expand Down Expand Up @@ -409,7 +413,8 @@ void createJsonRpcRouter(DevUIRecorder recorder,

DevConsoleManager.setGlobal(DevUIRecorder.DEV_MANAGER_GLOBALS_JSON_MAPPER_FACTORY,
JsonMapper.Factory.deploymentLinker().createLinkData(new DevUIDatabindCodec.Factory()));
recorder.createJsonRpcRouter(beanContainer.getValue(), extensionMethodsMap, deploymentMethodBuildItem.getMethods());
recorder.createJsonRpcRouter(beanContainer.getValue(), extensionMethodsMap, deploymentMethodBuildItem.getMethods(),
deploymentMethodBuildItem.getSubscriptions());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
public final class BuildTimeActionBuildItem extends AbstractDevUIBuildItem {

private final List<BuildTimeAction> actions = new ArrayList<>();
private final List<BuildTimeAction> subscriptions = new ArrayList<>();

public BuildTimeActionBuildItem() {
super();
Expand All @@ -34,4 +35,17 @@ public <T> void addAction(String methodName,
public List<BuildTimeAction> getActions() {
return actions;
}

public void addSubscription(BuildTimeAction buildTimeAction) {
this.subscriptions.add(buildTimeAction);
}

public <T> void addSubscription(String methodName,
Function<Map<String, String>, T> action) {
this.addSubscription(new BuildTimeAction(methodName, action));
}

public List<BuildTimeAction> getSubscriptions() {
return subscriptions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ public void shutdownTask(ShutdownContext shutdownContext, String devUIBasePath)

public void createJsonRpcRouter(BeanContainer beanContainer,
Map<String, Map<JsonRpcMethodName, JsonRpcMethod>> extensionMethodsMap,
List<String> deploymentMethods) {
List<String> deploymentMethods,
List<String> deploymentSubscriptions) {
JsonRpcRouter jsonRpcRouter = beanContainer.beanInstance(JsonRpcRouter.class);
jsonRpcRouter.populateJsonRPCRuntimeMethods(extensionMethodsMap);
jsonRpcRouter.setJsonRPCDeploymentMethods(deploymentMethods);
jsonRpcRouter.setJsonRPCDeploymentActions(deploymentMethods, deploymentSubscriptions);
jsonRpcRouter.initializeCodec(createJsonMapper());
}

Expand Down
Loading
Loading