This is an automated email from the ASF dual-hosted git repository. benweidig pushed a commit to branch TAP5-2838 in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
commit 25f24b40e3758f2b15d4a03966e856e354f44820 Author: Ben Weidig <[email protected]> AuthorDate: Sat Aug 8 12:55:49 2026 +0200 TAP5-2838: Add Pipelines page to T5Dashboard --- .../apache/tapestry5/corelib/pages/Pipelines.java | 73 ++++++++++++++++++++++ .../apache/tapestry5/modules/DashboardModule.java | 1 + .../apache/tapestry5/corelib/pages/Pipelines.tml | 60 ++++++++++++++++++ .../integration/app1/CoreBehaviorsTests.java | 16 +++++ 4 files changed, 150 insertions(+) diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/Pipelines.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/Pipelines.java new file mode 100644 index 000000000..bb2ccfa5b --- /dev/null +++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/Pipelines.java @@ -0,0 +1,73 @@ +// Copyright 2026 The Apache Software Foundation +// +// Licensed 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.tapestry5.corelib.pages; + +import java.util.List; + +import org.apache.tapestry5.annotations.Cached; +import org.apache.tapestry5.annotations.Property; +import org.apache.tapestry5.annotations.UnknownActivationContextCheck; +import org.apache.tapestry5.annotations.WhitelistAccessOnly; +import org.apache.tapestry5.http.TapestryHttpSymbolConstants; +import org.apache.tapestry5.ioc.annotations.Inject; +import org.apache.tapestry5.ioc.annotations.Symbol; +import org.apache.tapestry5.ioc.services.AssembledPipeline; +import org.apache.tapestry5.ioc.services.PipelineBuilder; + +/** + * Page used to see the pipelines assembled by the {@link PipelineBuilder}: which filters are in each pipeline, and + * in which order they are invoked. + * + * A pipeline is assembled when the service it implements is first realized, so this page shows more as the + * application runs. + * + * @since 5.10 + */ +@UnknownActivationContextCheck(false) +@WhitelistAccessOnly +public class Pipelines +{ + @Inject + private PipelineBuilder pipelineBuilder; + + @Property + @Inject + @Symbol(TapestryHttpSymbolConstants.PRODUCTION_MODE) + private boolean productionMode; + + @Property + private AssembledPipeline pipeline; + + @Property + private int pipelineIndex; + + @Property + private String filter; + + @Cached + public List<AssembledPipeline> getPipelines() + { + return pipelineBuilder.getAssembledPipelines(); + } + + /** + * Identifies the panel of the current pipeline, for the links at the top of the page. The index is used rather + * than the service interface, since the same interface may be the basis of more than one pipeline. + */ + public String getPipelineClientId() + { + return "pipeline-" + pipelineIndex; + } +} diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/DashboardModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/DashboardModule.java index c2938bf1e..01de67160 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/DashboardModule.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/DashboardModule.java @@ -40,6 +40,7 @@ public class DashboardModule { configuration.add("Pages", new DashboardTab("Pages", "core/PageCatalog")); configuration.add("Services", new DashboardTab("Services", "core/ServiceStatus")); + configuration.add("Pipelines", new DashboardTab("Pipelines", "core/Pipelines")); configuration.add("Libraries", new DashboardTab("ComponentLibraries", "core/ComponentLibraries")); configuration.add("PageDependencyGraph", new DashboardTab("PageDependencyGraph", "core/PageDependencyGraph")); if (!productionMode && multipleClassLoaders) diff --git a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/Pipelines.tml b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/Pipelines.tml new file mode 100644 index 000000000..555bbbb2b --- /dev/null +++ b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/Pipelines.tml @@ -0,0 +1,60 @@ +<t:block id="content" + xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:p="tapestry:parameter"> + + <t:unless test="productionMode"> + <p:then> + <p> + <strong>${pipelines.size()}</strong> pipelines assembled so far. + A pipeline is assembled when the service it implements is first realized, + so this list grows as the application runs. + </p> + <ul class="list-group"> + <li class="list-group-item" t:type="Loop" t:source="pipelines" t:value="pipeline" + index="pipelineIndex"> + <span class="badge">${pipeline.filters.size()}</span> + <a href="#${pipelineClientId}"> + <code>${pipeline.serviceInterface.simpleName}</code> + </a> + </li> + </ul> + + <div class="panel panel-default" t:type="Loop" t:source="pipelines" t:value="pipeline" + index="pipelineIndex" id="${pipelineClientId}"> + + <div class="panel-heading"> + <code>${pipeline.serviceInterface.name}</code> + </div> + + <div class="panel-body"> + <p> + Filtered by: <code>${pipeline.filterInterface.name}</code> + </p> + + <t:if test="pipeline.filters.empty"> + <p:then> + <p class="text-muted">No filters contributed; the pipeline is just its terminator.</p> + </p:then> + <p:else> + <ol> + <li t:type="Loop" t:source="pipeline.filters" t:value="filter"> + <code>${filter}</code> + </li> + </ol> + </p:else> + </t:if> + + <p> + Terminator: + <code>${pipeline.terminator}</code> + </p> + </div> + </div> + </p:then> + <p:else> + <p> + <em>The filters of each pipeline are only shown in development mode.</em> + </p> + </p:else> + </t:unless> + +</t:block> diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java index a7a538510..b46c1c0e9 100644 --- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java +++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java @@ -14,6 +14,7 @@ package org.apache.tapestry5.integration.app1; import org.apache.tapestry5.corelib.mixins.RenderDisabled; import org.apache.tapestry5.integration.app1.pages.RenderErrorDemo; +import org.apache.tapestry5.services.ComponentRequestHandler; import org.openqa.selenium.By; import org.openqa.selenium.support.ui.ExpectedConditions; import org.testng.annotations.Test; @@ -743,6 +744,21 @@ public class CoreBehaviorsTests extends App1TestCase assertTextPresent("services defined in the IoC Registry"); } + /** + * This basically checks that the pipelines page does not error. + */ + @Test + public void pipelines() + { + open(getBaseURL() + "t5dashboard/pipelines"); + + assertTextPresent("pipelines assembled so far"); + + // Every request goes through this pipeline, so it has certainly been assembled by now. + + assertTextPresent(ComponentRequestHandler.class.getName()); + } + /** * Tests TAPESTRY-1934. */
