From 0f238143b3dbc4ffa3115baa4a864364a3140f2b Mon Sep 17 00:00:00 2001 From: Michal Petrov Date: Fri, 11 Sep 2026 17:30:42 +0200 Subject: [PATCH] HAL-2063: fix resource name retrieval in FinderColumns --- .../subsystem/infinispan/CacheColumn.java | 57 ++++---- .../messaging/ServerSettingsColumn.java | 127 +++++++++--------- .../subsystem/undertow/HostColumn.java | 8 +- .../messaging/DestinationColumn.java | 93 ++++++------- .../resourceadapter/ChildResourceColumn.java | 82 ++++++----- .../subsystem/undertow/ListenerColumn.java | 102 +++++++------- .../undertow/ModclusterBalancerColumn.java | 29 ++-- .../ModclusterBalancerNodeColumn.java | 38 ++---- .../ModclusterBalancerNodeContextColumn.java | 44 +++--- .../core/finder/DependentItemsProvider.java | 96 +++++++++++++ 10 files changed, 353 insertions(+), 323 deletions(-) create mode 100644 core/src/main/java/org/jboss/hal/core/finder/DependentItemsProvider.java diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/CacheColumn.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/CacheColumn.java index d5ac8b8e5b..8ab8d09c2a 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/CacheColumn.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/CacheColumn.java @@ -24,10 +24,9 @@ import org.jboss.hal.core.CrudOperations; import org.jboss.hal.core.finder.ColumnAction; import org.jboss.hal.core.finder.ColumnActionFactory; +import org.jboss.hal.core.finder.DependentItemsProvider; import org.jboss.hal.core.finder.Finder; import org.jboss.hal.core.finder.FinderColumn; -import org.jboss.hal.core.finder.FinderPath; -import org.jboss.hal.core.finder.FinderSegment; import org.jboss.hal.core.finder.ItemAction; import org.jboss.hal.core.finder.ItemActionFactory; import org.jboss.hal.core.finder.ItemDisplay; @@ -64,7 +63,6 @@ import static java.util.Arrays.asList; import static java.util.Arrays.stream; -import static java.util.Collections.emptyList; import static java.util.Comparator.comparing; import static java.util.stream.Collectors.toList; @@ -91,12 +89,12 @@ SCATTERED_CACHE_ADDRESS }, recursive = false) public class CacheColumn extends FinderColumn { - private static String findCacheContainer(FinderPath path) { - FinderSegment segment = path.findColumn(Ids.CACHE_CONTAINER); - if (segment != null) { - return Ids.extractCacheContainer(segment.getItemId()); - } - return null; + private static String getCacheContainerId() { + return Ids.CACHE_CONTAINER; + } + + private String findCacheContainer() { + return DependentItemsProvider.resolver(getCacheContainerId(), getFinder().getContext().getPath()).getName(); } private static final String JGROUPS_ADDITION_STATUS = "jgrupsAdditionStatus"; @@ -123,28 +121,23 @@ public CacheColumn(Finder finder, EventBus eventBus) { super(new Builder(finder, Ids.CACHE, Names.CACHE) - .itemsProvider(context -> new Promise<>((resolve, reject) -> { - String cacheContainer = findCacheContainer(context.getPath()); - if (cacheContainer != null) { - CacheType[] cacheTypes = CacheType.values(); - ResourceAddress address = CACHE_CONTAINER_TEMPLATE.resolve(statementContext, cacheContainer); - List children = stream(cacheTypes).map(CacheType::resource).collect(toList()); - crud.readChildren(address, children, 1, result -> { - List caches = new ArrayList<>(); - for (int i = 0; i < result.size(); i++) { - List properties = result.step(i).get(RESULT).asPropertyList(); - for (Property property : properties) { - caches.add(new Cache(property.getName(), cacheTypes[i], property.getValue())); + .itemsProvider(new DependentItemsProvider( + cacheContainer -> new Promise<>((resolve, reject) -> { + CacheType[] cacheTypes = CacheType.values(); + ResourceAddress address = CACHE_CONTAINER_TEMPLATE.resolve(statementContext, cacheContainer); + List children = stream(cacheTypes).map(CacheType::resource).collect(toList()); + crud.readChildren(address, children, 1, result -> { + List caches = new ArrayList<>(); + for (int i = 0; i < result.size(); i++) { + List properties = result.step(i).get(RESULT).asPropertyList(); + for (Property property : properties) { + caches.add(new Cache(property.getName(), cacheTypes[i], property.getValue())); + } } - } - // Collections.sort(caches, (c1, c2) -> c1.getName().compareTo(c2.getName())); - caches.sort(comparing(NamedNode::getName)); - resolve.onInvoke(caches); - }); - } else { - resolve.onInvoke(emptyList()); - } - })) + caches.sort(comparing(NamedNode::getName)); + resolve.onInvoke(caches); + }); + }), getCacheContainerId())) .onPreview(CachePreview::new) .pinnable() .showCount() @@ -203,7 +196,7 @@ public String getFilterData() { @Override public List> actions() { List> actions = new ArrayList<>(); - String cacheContainer = findCacheContainer(getFinder().getContext().getPath()); + String cacheContainer = findCacheContainer(); if (cacheContainer != null) { actions.add(itemActionFactory.viewAndMonitor(Ids.build(item.type().baseId, item.getName()), places.selectedProfile(item.type().nameToken) @@ -231,7 +224,7 @@ private void addCache(CacheType cacheType) { AddResourceDialog dialog = new AddResourceDialog(Ids.build(cacheType.baseId, Ids.ADD), resources.messages().addResourceTitle(cacheType.type), metadata, (name, model) -> { - String cacheContainer = findCacheContainer(getFinder().getContext().getPath()); + String cacheContainer = findCacheContainer(); ResourceAddress address = cacheType.template.resolve(statementContext, cacheContainer, name); if (cacheType.equals(CacheType.LOCAL)) { diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ServerSettingsColumn.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ServerSettingsColumn.java index ab180889d9..3f02215f36 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ServerSettingsColumn.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ServerSettingsColumn.java @@ -21,9 +21,9 @@ import javax.inject.Inject; import org.jboss.hal.core.CrudOperations; +import org.jboss.hal.core.finder.DependentItemsProvider; import org.jboss.hal.core.finder.Finder; import org.jboss.hal.core.finder.FinderColumn; -import org.jboss.hal.core.finder.FinderSegment; import org.jboss.hal.core.finder.ItemAction; import org.jboss.hal.core.finder.ItemActionFactory; import org.jboss.hal.core.finder.PreviewContent; @@ -90,75 +90,70 @@ public ServerSettingsColumn(Finder finder, this.dispatcher = dispatcher; this.resources = resources; - setItemsProvider(context -> new Promise<>((resolve, reject) -> { - List items = new ArrayList<>(); - FinderSegment segment = context.getPath().findColumn(Ids.MESSAGING_SERVER_CONFIGURATION); - if (segment != null) { - String server = segment.getItemTitle(); - StatementContext serverStatementContext = new SelectionAwareStatementContext(statementContext, - () -> server); - ResourceAddress address = SELECTED_SERVER_TEMPLATE.resolve(serverStatementContext); - HaPolicy.readChildren(crud, address, 1, children -> { - - items.add(new StaticItem.Builder(Names.DESTINATIONS) - .id(Ids.MESSAGING_SERVER_DESTINATION) - .action(itemActionFactory.view( - places.selectedProfile(NameTokens.MESSAGING_SERVER_DESTINATION) - .with(SERVER, server) - .build())) - .onPreview(new PreviewContent<>(Names.DESTINATIONS, - resources.previews().configurationMessagingDestinations())) - .build()); - items.add(new StaticItem.Builder(Names.CONNECTIONS) - .id(Ids.MESSAGING_SERVER_CONNECTION) - .action(itemActionFactory.view( - places.selectedProfile(NameTokens.MESSAGING_SERVER_CONNECTION) - .with(SERVER, server) - .build())) - .onPreview(new PreviewContent<>(Names.CONNECTIONS, - resources.previews().configurationMessagingConnections())) - .build()); - items.add(new StaticItem.Builder(Names.CLUSTERING) - .id(Ids.MESSAGING_SERVER_CLUSTERING) - .action(itemActionFactory.view( - places.selectedProfile(NameTokens.MESSAGING_SERVER_CLUSTERING) - .with(SERVER, server) - .build())) - .onPreview(new PreviewContent<>(Names.CLUSTERING, - resources.previews().configurationMessagingClustering())) - .build()); - - StaticItem.Builder builder = new StaticItem.Builder(Names.HA_POLICY) - .id(Ids.MESSAGING_SERVER_HA_POLICY); - if (children.isEmpty()) { - builder.action(resources.constants().add(), item -> addHaPolicy(serverStatementContext)) + setItemsProvider(new DependentItemsProvider( + parentNames -> new Promise<>((resolve, reject) -> { + List items = new ArrayList<>(); + String server = parentNames[0]; + StatementContext serverStatementContext = new SelectionAwareStatementContext(statementContext, + () -> server); + ResourceAddress address = SELECTED_SERVER_TEMPLATE.resolve(serverStatementContext); + HaPolicy.readChildren(crud, address, 1, children -> { + + items.add(new StaticItem.Builder(Names.DESTINATIONS) + .id(Ids.MESSAGING_SERVER_DESTINATION) .action(itemActionFactory.view( - places.selectedProfile(NameTokens.MESSAGING_SERVER_HA_POLICY) + places.selectedProfile(NameTokens.MESSAGING_SERVER_DESTINATION) .with(SERVER, server) .build())) - .onPreview(new PreviewContent<>(Names.HA_POLICY, - resources.previews().configurationMessagingHaPolicy())); - - } else { - Property child = children.get(0); - HaPolicy haPolicy = HaPolicy.fromResourceName(child.getName()); - builder.action(itemActionFactory.view( - places.selectedProfile(NameTokens.MESSAGING_SERVER_HA_POLICY) - .with(SERVER, server) - .build())) - .action(resources.constants().remove(), - item -> removeHaPolicy(serverStatementContext, haPolicy)) - .onPreview(new HaPolicyPreview(haPolicy, child.getValue())); - } - items.add(builder.build()); - - resolve.onInvoke(items); - }); + .onPreview(new PreviewContent<>(Names.DESTINATIONS, + resources.previews().configurationMessagingDestinations())) + .build()); + items.add(new StaticItem.Builder(Names.CONNECTIONS) + .id(Ids.MESSAGING_SERVER_CONNECTION) + .action(itemActionFactory.view( + places.selectedProfile(NameTokens.MESSAGING_SERVER_CONNECTION) + .with(SERVER, server) + .build())) + .onPreview(new PreviewContent<>(Names.CONNECTIONS, + resources.previews().configurationMessagingConnections())) + .build()); + items.add(new StaticItem.Builder(Names.CLUSTERING) + .id(Ids.MESSAGING_SERVER_CLUSTERING) + .action(itemActionFactory.view( + places.selectedProfile(NameTokens.MESSAGING_SERVER_CLUSTERING) + .with(SERVER, server) + .build())) + .onPreview(new PreviewContent<>(Names.CLUSTERING, + resources.previews().configurationMessagingClustering())) + .build()); + + StaticItem.Builder builder = new StaticItem.Builder(Names.HA_POLICY) + .id(Ids.MESSAGING_SERVER_HA_POLICY); + if (children.isEmpty()) { + builder.action(resources.constants().add(), item -> addHaPolicy(serverStatementContext)) + .action(itemActionFactory.view( + places.selectedProfile(NameTokens.MESSAGING_SERVER_HA_POLICY) + .with(SERVER, server) + .build())) + .onPreview(new PreviewContent<>(Names.HA_POLICY, + resources.previews().configurationMessagingHaPolicy())); + + } else { + Property child = children.get(0); + HaPolicy haPolicy = HaPolicy.fromResourceName(child.getName()); + builder.action(itemActionFactory.view( + places.selectedProfile(NameTokens.MESSAGING_SERVER_HA_POLICY) + .with(SERVER, server) + .build())) + .action(resources.constants().remove(), + item -> removeHaPolicy(serverStatementContext, haPolicy)) + .onPreview(new HaPolicyPreview(haPolicy, child.getValue())); + } + items.add(builder.build()); - } else { - resolve.onInvoke(items); - } - })); + resolve.onInvoke(items); + }); + }), Ids.MESSAGING_SERVER_CONFIGURATION)); } private void addHaPolicy(StatementContext statementContext) { diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/HostColumn.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/HostColumn.java index dc7d32a78c..fcaee4e80b 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/HostColumn.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/HostColumn.java @@ -22,9 +22,9 @@ import org.jboss.hal.core.CrudOperations; import org.jboss.hal.core.finder.ColumnActionFactory; +import org.jboss.hal.core.finder.DependentItemsProvider; import org.jboss.hal.core.finder.Finder; import org.jboss.hal.core.finder.FinderColumn; -import org.jboss.hal.core.finder.FinderSegment; import org.jboss.hal.core.finder.ItemAction; import org.jboss.hal.core.finder.ItemActionFactory; import org.jboss.hal.core.finder.ItemDisplay; @@ -149,10 +149,6 @@ private StatementContext selectionAwareStatementContext() { } private String findServer() { - FinderSegment segment = getFinder().getContext().getPath().findColumn(Ids.UNDERTOW_SERVER); - if (segment != null) { - return Ids.extractUndertowServer(segment.getItemId()); - } - return null; + return DependentItemsProvider.resolver(Ids.UNDERTOW_SERVER, getFinder().getContext().getPath()).getName(); } } diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/messaging/DestinationColumn.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/messaging/DestinationColumn.java index e7b381a1c3..bc829b73d1 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/messaging/DestinationColumn.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/messaging/DestinationColumn.java @@ -24,10 +24,10 @@ import org.jboss.hal.ballroom.dialog.DialogFactory; import org.jboss.hal.client.runtime.subsystem.messaging.Destination.Type; import org.jboss.hal.core.finder.ColumnActionFactory; +import org.jboss.hal.core.finder.DependentItemsProvider; import org.jboss.hal.core.finder.Finder; import org.jboss.hal.core.finder.FinderColumn; import org.jboss.hal.core.finder.FinderPathFactory; -import org.jboss.hal.core.finder.FinderSegment; import org.jboss.hal.core.finder.ItemAction; import org.jboss.hal.core.finder.ItemActionFactory; import org.jboss.hal.core.finder.ItemDisplay; @@ -58,7 +58,6 @@ import elemental2.dom.HTMLElement; import elemental2.promise.Promise; -import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; import static org.jboss.hal.client.runtime.subsystem.messaging.AddressTemplates.MESSAGING_CORE_QUEUE_ADDRESS; @@ -83,7 +82,6 @@ import static org.jboss.hal.dmr.ModelDescriptionConstants.RESULT; import static org.jboss.hal.dmr.ModelDescriptionConstants.RESUME; import static org.jboss.hal.dmr.ModelDescriptionConstants.SUBDEPLOYMENT; -import static org.jboss.hal.dmr.ModelDescriptionConstants.UNDEFINED; import static org.jboss.hal.resources.CSS.fontAwesome; @AsyncColumn(Ids.MESSAGING_SERVER_DESTINATION_RUNTIME) @@ -123,47 +121,42 @@ public DestinationColumn(Finder finder, this.eventBus = eventBus; this.resources = resources; - ItemsProvider itemsProvider = context -> { - // extract server name from the finder path - FinderSegment segment = context.getPath().findColumn(Ids.MESSAGING_SERVER_RUNTIME); - if (segment != null) { - String server = segment.getItemTitle(); - List operations = new ArrayList<>(); - for (Type type : SUBSYSTEM_RESOURCES) { - ResourceAddress address = MESSAGING_SERVER_TEMPLATE.append(type.resource + "=*") - .resolve(statementContext, server); - operations.add(new Operation.Builder(address, READ_RESOURCE_OPERATION) - .param(INCLUDE_RUNTIME, true) - .build()); - } - for (Type type : DEPLOYMENT_RESOURCES) { - ResourceAddress address = MESSAGING_DEPLOYMENT_TEMPLATE.append(type.resource + "=*") - .resolve(statementContext); - operations.add(new Operation.Builder(address, READ_RESOURCE_OPERATION) - .param(INCLUDE_RUNTIME, true) - .build()); - } - return dispatcher.execute(new Composite(operations)).then(result -> { - List destinations = new ArrayList<>(); - for (ModelNode step : result) { - if (!step.isFailure()) { - for (ModelNode node : step.get(RESULT).asList()) { - AddressTemplate template = AddressTemplate.of(new ResourceAddress(node.get(ADDRESS))); - if (!template.firstName().equals(HOST)) { - // Add correct host and server before the messaging address if it is missing - template = SELECTED_HOST_SELECTED_SERVER_TEMPLATE.append(template); + ItemsProvider itemsProvider = new DependentItemsProvider( + server -> { + List operations = new ArrayList<>(); + for (Type type : SUBSYSTEM_RESOURCES) { + ResourceAddress address = MESSAGING_SERVER_TEMPLATE.append(type.resource + "=*") + .resolve(statementContext, server); + operations.add(new Operation.Builder(address, READ_RESOURCE_OPERATION) + .param(INCLUDE_RUNTIME, true) + .build()); + } + for (Type type : DEPLOYMENT_RESOURCES) { + ResourceAddress address = MESSAGING_DEPLOYMENT_TEMPLATE.append(type.resource + "=*") + .resolve(statementContext); + operations.add(new Operation.Builder(address, READ_RESOURCE_OPERATION) + .param(INCLUDE_RUNTIME, true) + .build()); + } + return dispatcher.execute(new Composite(operations)).then(result -> { + List destinations = new ArrayList<>(); + for (ModelNode step : result) { + if (!step.isFailure()) { + for (ModelNode node : step.get(RESULT).asList()) { + AddressTemplate template = AddressTemplate.of(new ResourceAddress(node.get(ADDRESS))); + if (!template.firstName().equals(HOST)) { + // Add correct host and server before the messaging address if it is missing + template = SELECTED_HOST_SELECTED_SERVER_TEMPLATE.append(template); + } + destinations.add(new Destination(template.resolve(statementContext), node.get(RESULT))); } - destinations.add(new Destination(template.resolve(statementContext), node.get(RESULT))); } } - } - destinations.sort(Comparator.comparing(NamedNode::getName)); - return Promise.resolve(destinations); - }); - } else { - return Promise.resolve(emptyList()); - } - }; + destinations.sort(Comparator.comparing(NamedNode::getName)); + return Promise.resolve(destinations); + }); + }, + getServerId()); setItemsProvider(itemsProvider); setBreadcrumbItemsProvider(context -> itemsProvider.items(context) .then(result -> Promise.resolve(result.stream() @@ -173,7 +166,8 @@ public DestinationColumn(Finder finder, setItemRenderer(item -> new ItemDisplay() { @Override public String getId() { - return Ids.destination(item.getDeployment(), item.getSubdeployment(), messageServer(), item.type.name(), + return Ids.destination(item.getDeployment(), item.getSubdeployment(), findMessageServer(), + item.type.name(), item.getName()); } @@ -231,7 +225,7 @@ public List> actions() { builder.with(SUBDEPLOYMENT, item.getSubdeployment()); } } - builder.with(Ids.MESSAGING_SERVER, messageServer()).with(NAME, item.getName()); + builder.with(Ids.MESSAGING_SERVER, findMessageServer()).with(NAME, item.getName()); actions.add(itemActionFactory.view(builder.build())); } else if (item.type == Type.JMS_TOPIC) { actions.add(new ItemAction.Builder() @@ -260,13 +254,12 @@ public List> actions() { }); } - private String messageServer() { - String server = UNDEFINED; - FinderSegment segment = getFinder().getContext().getPath().findColumn(Ids.MESSAGING_SERVER_RUNTIME); - if (segment != null) { - server = Ids.extractMessagingServer(segment.getItemId()); - } - return server; + private String getServerId() { + return Ids.MESSAGING_SERVER_RUNTIME; + } + + private String findMessageServer() { + return DependentItemsProvider.resolver(getServerId(), getFinder().getContext().getPath()).getName(); } private void resume(Destination destination) { diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/resourceadapter/ChildResourceColumn.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/resourceadapter/ChildResourceColumn.java index c3e58a5b2e..bf9e6b1c8f 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/resourceadapter/ChildResourceColumn.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/resourceadapter/ChildResourceColumn.java @@ -16,15 +16,14 @@ package org.jboss.hal.client.runtime.subsystem.resourceadapter; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import javax.inject.Inject; import org.jboss.hal.config.Environment; +import org.jboss.hal.core.finder.DependentItemsProvider; import org.jboss.hal.core.finder.Finder; import org.jboss.hal.core.finder.FinderColumn; -import org.jboss.hal.core.finder.FinderSegment; import org.jboss.hal.core.finder.ItemAction; import org.jboss.hal.core.finder.ItemActionFactory; import org.jboss.hal.core.finder.ItemDisplay; @@ -95,50 +94,45 @@ public ChildResourceColumn(ServerActions serverActions, .filterDescription(resources.messages().filterBy("name, type")) .useFirstActionAsBreadcrumbHandler()); - ItemsProvider itemsProvider = context -> { - // extract server name from the finder path - FinderSegment segment = context.getPath().findColumn(Ids.RESOURCE_ADAPTER_RUNTIME); - - if (segment != null) { - String raName = segment.getItemTitle(); - List operations = new ArrayList<>(); - - ResourceAddress resourceAdapterAddress = RESOURCE_ADAPTER_TEMPLATE.resolve(statementContext, raName); - operations.add(new Operation.Builder(resourceAdapterAddress, READ_CHILDREN_RESOURCES_OPERATION) - .param(CHILD_TYPE, ADMIN_OBJECTS) - .param(INCLUDE_RUNTIME, true) - .param(RECURSIVE_DEPTH, 2) - .build()); - - operations.add(new Operation.Builder(resourceAdapterAddress, READ_CHILDREN_RESOURCES_OPERATION) - .param(CHILD_TYPE, CONNECTION_DEFINITIONS) - .param(INCLUDE_RUNTIME, true) - .param(RECURSIVE_DEPTH, 2) - .build()); - - if (!environment.isStandalone()) { - ResourceAddress serverAddress = AddressTemplate.of(SELECTED_HOST, SELECTED_SERVER) - .resolve(statementContext); - operations.add(new Operation.Builder(serverAddress, READ_RESOURCE_OPERATION) + ItemsProvider itemsProvider = new DependentItemsProvider( + parentNames -> { + String raName = parentNames[0]; + List operations = new ArrayList<>(); + + ResourceAddress resourceAdapterAddress = RESOURCE_ADAPTER_TEMPLATE.resolve(statementContext, raName); + operations.add(new Operation.Builder(resourceAdapterAddress, READ_CHILDREN_RESOURCES_OPERATION) + .param(CHILD_TYPE, ADMIN_OBJECTS) .param(INCLUDE_RUNTIME, true) - .param(ATTRIBUTES_ONLY, true) + .param(RECURSIVE_DEPTH, 2) .build()); - } - return dispatcher.execute(new Composite(operations)).then(result -> { - server = environment.isStandalone() - ? Server.STANDALONE - : new Server(statementContext.selectedHost(), result.step(2).get(RESULT)); - List combined = new ArrayList<>(); - combined.addAll(result.step(0).get(RESULT).asPropertyList().stream() - .map(ao -> new StatisticsResource(raName, ADMIN_OBJECT, ao)).collect(toList())); - combined.addAll(result.step(1).get(RESULT).asPropertyList().stream() - .map(cd -> new StatisticsResource(raName, CONNECTION_DEFINITION, cd)).collect(toList())); - combined.sort(comparing(NamedNode::getName)); - return Promise.resolve(combined); - }); - } - return Promise.resolve(Collections.emptyList()); - }; + + operations.add(new Operation.Builder(resourceAdapterAddress, READ_CHILDREN_RESOURCES_OPERATION) + .param(CHILD_TYPE, CONNECTION_DEFINITIONS) + .param(INCLUDE_RUNTIME, true) + .param(RECURSIVE_DEPTH, 2) + .build()); + + if (!environment.isStandalone()) { + ResourceAddress serverAddress = AddressTemplate.of(SELECTED_HOST, SELECTED_SERVER) + .resolve(statementContext); + operations.add(new Operation.Builder(serverAddress, READ_RESOURCE_OPERATION) + .param(INCLUDE_RUNTIME, true) + .param(ATTRIBUTES_ONLY, true) + .build()); + } + return dispatcher.execute(new Composite(operations)).then(result -> { + server = environment.isStandalone() + ? Server.STANDALONE + : new Server(statementContext.selectedHost(), result.step(2).get(RESULT)); + List combined = new ArrayList<>(); + combined.addAll(result.step(0).get(RESULT).asPropertyList().stream() + .map(ao -> new StatisticsResource(raName, ADMIN_OBJECT, ao)).collect(toList())); + combined.addAll(result.step(1).get(RESULT).asPropertyList().stream() + .map(cd -> new StatisticsResource(raName, CONNECTION_DEFINITION, cd)).collect(toList())); + combined.sort(comparing(NamedNode::getName)); + return Promise.resolve(combined); + }); + }, Ids.RESOURCE_ADAPTER_RUNTIME); setItemsProvider(itemsProvider); // reuse the items provider to filter breadcrumb items diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ListenerColumn.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ListenerColumn.java index 3050f0399f..31d7e7dbf2 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ListenerColumn.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ListenerColumn.java @@ -22,9 +22,9 @@ import org.jboss.hal.ballroom.dialog.DialogFactory; import org.jboss.hal.core.finder.ColumnActionFactory; +import org.jboss.hal.core.finder.DependentItemsProvider; import org.jboss.hal.core.finder.Finder; import org.jboss.hal.core.finder.FinderColumn; -import org.jboss.hal.core.finder.FinderSegment; import org.jboss.hal.core.finder.ItemAction; import org.jboss.hal.core.finder.ItemDisplay; import org.jboss.hal.dmr.Composite; @@ -48,8 +48,6 @@ import elemental2.promise.Promise; -import static java.util.Collections.emptyList; - import static org.jboss.hal.client.runtime.subsystem.undertow.AddressTemplates.AJP_LISTENER_ADDRESS; import static org.jboss.hal.client.runtime.subsystem.undertow.AddressTemplates.AJP_LISTENER_TEMPLATE; import static org.jboss.hal.client.runtime.subsystem.undertow.AddressTemplates.WEB_SERVER_ADDRESS; @@ -87,58 +85,54 @@ public ListenerColumn(Finder finder, super(new Builder(finder, Ids.UNDERTOW_RUNTIME_LISTENER, Names.LISTENER) .columnAction(columnActionFactory.refresh(Ids.UNDERTOW_LISTENER_REFRESH)) - .itemsProvider(context -> { - // extract server name from the finder path - FinderSegment segment = context.getPath().findColumn(Ids.UNDERTOW_RUNTIME_SERVER); - if (segment != null) { - String server = Ids.extractUndertowServer(segment.getItemId()); - ResourceAddress address = WEB_SERVER_TEMPLATE.resolve(statementContext, server); - - Operation opAjp = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) - .param(CHILD_TYPE, AJP_LISTENER) - .param(INCLUDE_RUNTIME, true) - .build(); - Operation opHttp = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) - .param(CHILD_TYPE, HTTP_LISTENER) - .param(INCLUDE_RUNTIME, true) - .build(); - Operation opHttps = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) - .param(CHILD_TYPE, HTTPS_LISTENER) - .param(INCLUDE_RUNTIME, true) - .build(); - - return dispatcher.execute(new Composite(opAjp, opHttp, opHttps)).then(result -> { - - List ajpProps = result.step(0).get(RESULT).asPropertyList(); - List httpProps = result.step(1).get(RESULT).asPropertyList(); - List httpsProps = result.step(2).get(RESULT).asPropertyList(); - // add the listener type and undertow server to the result, because the preview pane - // contains a link to refresh the values, that it call a :read-resource operation - // and the listener-type and undertow server is part of the resource address. - ajpProps.forEach(p -> { - p.getValue().get(HAL_LISTENER_TYPE).set(AJP_LISTENER); - p.getValue().get(HAL_WEB_SERVER).set(server); - }); - httpProps.forEach(p -> { - p.getValue().get(HAL_LISTENER_TYPE).set(HTTP_LISTENER); - p.getValue().get(HAL_WEB_SERVER).set(server); + .itemsProvider(new DependentItemsProvider( + parentNames -> { + String server = parentNames[0]; + ResourceAddress address = WEB_SERVER_TEMPLATE.resolve(statementContext, server); + + Operation opAjp = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) + .param(CHILD_TYPE, AJP_LISTENER) + .param(INCLUDE_RUNTIME, true) + .build(); + Operation opHttp = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) + .param(CHILD_TYPE, HTTP_LISTENER) + .param(INCLUDE_RUNTIME, true) + .build(); + Operation opHttps = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) + .param(CHILD_TYPE, HTTPS_LISTENER) + .param(INCLUDE_RUNTIME, true) + .build(); + + return dispatcher.execute(new Composite(opAjp, opHttp, opHttps)).then(result -> { + + List ajpProps = result.step(0).get(RESULT).asPropertyList(); + List httpProps = result.step(1).get(RESULT).asPropertyList(); + List httpsProps = result.step(2).get(RESULT).asPropertyList(); + // add the listener type and undertow server to the result, because the preview pane + // contains a link to refresh the values, that it call a :read-resource operation + // and the listener-type and undertow server is part of the resource address. + ajpProps.forEach(p -> { + p.getValue().get(HAL_LISTENER_TYPE).set(AJP_LISTENER); + p.getValue().get(HAL_WEB_SERVER).set(server); + }); + httpProps.forEach(p -> { + p.getValue().get(HAL_LISTENER_TYPE).set(HTTP_LISTENER); + p.getValue().get(HAL_WEB_SERVER).set(server); + }); + httpsProps.forEach(p -> { + p.getValue().get(HAL_LISTENER_TYPE).set(HTTPS_LISTENER); + p.getValue().get(HAL_WEB_SERVER).set(server); + }); + + List listeners = new ArrayList<>(); + listeners.addAll(asNamedNodes(ajpProps)); + listeners.addAll(asNamedNodes(httpProps)); + listeners.addAll(asNamedNodes(httpsProps)); + + return Promise.resolve(listeners); }); - httpsProps.forEach(p -> { - p.getValue().get(HAL_LISTENER_TYPE).set(HTTPS_LISTENER); - p.getValue().get(HAL_WEB_SERVER).set(server); - }); - - List listeners = new ArrayList<>(); - listeners.addAll(asNamedNodes(ajpProps)); - listeners.addAll(asNamedNodes(httpProps)); - listeners.addAll(asNamedNodes(httpsProps)); - - return Promise.resolve(listeners); - }); - } else { - return Promise.resolve(emptyList()); - } - }) + }, + Ids.UNDERTOW_RUNTIME_SERVER)) .onPreview(server -> new ListenerPreview(dispatcher, statementContext, resources, server))); this.dispatcher = dispatcher; this.resources = resources; diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerColumn.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerColumn.java index e7615c63a9..2784728793 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerColumn.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerColumn.java @@ -18,9 +18,9 @@ import javax.inject.Inject; import org.jboss.hal.core.finder.ColumnActionFactory; +import org.jboss.hal.core.finder.DependentItemsProvider; import org.jboss.hal.core.finder.Finder; import org.jboss.hal.core.finder.FinderColumn; -import org.jboss.hal.core.finder.FinderSegment; import org.jboss.hal.core.finder.ItemDisplay; import org.jboss.hal.dmr.NamedNode; import org.jboss.hal.dmr.Operation; @@ -33,8 +33,6 @@ import elemental2.promise.Promise; -import static java.util.Collections.emptyList; - import static org.jboss.hal.client.runtime.subsystem.undertow.AddressTemplates.MODCLUSTER_TEMPLATE; import static org.jboss.hal.dmr.ModelDescriptionConstants.BALANCER; import static org.jboss.hal.dmr.ModelDescriptionConstants.CHILD_TYPE; @@ -55,21 +53,16 @@ public ModclusterBalancerColumn(Finder finder, super(new Builder(finder, Ids.UNDERTOW_RUNTIME_MODCLUSTER_BALANCER, Names.BALANCER) .columnAction(columnActionFactory.refresh(Ids.UNDERTOW_MODCLUSTER_BALANCER_REFRESH)) - .itemsProvider(context -> { - FinderSegment segment = context.getPath().findColumn(Ids.UNDERTOW_RUNTIME_MODCLUSTER); - if (segment != null) { - String modcluster = Ids.extractUndertowModcluster(segment.getItemId()); - ResourceAddress address = MODCLUSTER_TEMPLATE.resolve(statementContext, modcluster); - Operation operation = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) - .param(CHILD_TYPE, BALANCER) - .param(INCLUDE_RUNTIME, true) - .build(); - return dispatcher.execute(operation) - .then(result -> Promise.resolve(asNamedNodes(result.asPropertyList()))); - } else { - return Promise.resolve(emptyList()); - } - }) + .itemsProvider(new DependentItemsProvider( + modcluster -> { + ResourceAddress address = MODCLUSTER_TEMPLATE.resolve(statementContext, modcluster); + Operation operation = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) + .param(CHILD_TYPE, BALANCER) + .param(INCLUDE_RUNTIME, true) + .build(); + return dispatcher.execute(operation) + .then(result -> Promise.resolve(asNamedNodes(result.asPropertyList()))); + }, Ids.UNDERTOW_RUNTIME_MODCLUSTER)) .itemRenderer(item -> new ItemDisplay() { @Override public String getId() { diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerNodeColumn.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerNodeColumn.java index 8e8b3b9f1f..d45085b489 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerNodeColumn.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerNodeColumn.java @@ -18,9 +18,9 @@ import javax.inject.Inject; import org.jboss.hal.core.finder.ColumnActionFactory; +import org.jboss.hal.core.finder.DependentItemsProvider; import org.jboss.hal.core.finder.Finder; import org.jboss.hal.core.finder.FinderColumn; -import org.jboss.hal.core.finder.FinderSegment; import org.jboss.hal.core.finder.ItemDisplay; import org.jboss.hal.dmr.NamedNode; import org.jboss.hal.dmr.Operation; @@ -54,29 +54,19 @@ public ModclusterBalancerNodeColumn(Finder finder, super(new Builder(finder, Ids.UNDERTOW_RUNTIME_MODCLUSTER_BALANCER_NODE, Names.NODE) .columnAction(columnActionFactory.refresh(Ids.UNDERTOW_MODCLUSTER_BALANCER_NODE_REFRESH)) - .itemsProvider(context -> { - String modcluster = ""; - String balancer = ""; - - FinderSegment modclusterSegment = context.getPath().findColumn(Ids.UNDERTOW_RUNTIME_MODCLUSTER); - if (modclusterSegment != null) { - modcluster = Ids.extractUndertowModcluster(modclusterSegment.getItemId()); - } - - FinderSegment balancerSegment = context.getPath().findColumn(Ids.UNDERTOW_RUNTIME_MODCLUSTER_BALANCER); - if (balancerSegment != null) { - balancer = Ids.extractUndertowModclusterBalancer(balancerSegment.getItemId()); - } - - ResourceAddress address = MODCLUSTER_BALANCER_TEMPLATE.resolve(statementContext, modcluster, - balancer); - Operation operation = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) - .param(CHILD_TYPE, NODE) - .param(INCLUDE_RUNTIME, true) - .build(); - return dispatcher.execute(operation) - .then(result -> Promise.resolve(asNamedNodes(result.asPropertyList()))); - }) + .itemsProvider(new DependentItemsProvider( + parentNames -> { + ResourceAddress address = MODCLUSTER_BALANCER_TEMPLATE.resolve(statementContext, + parentNames); + Operation operation = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) + .param(CHILD_TYPE, NODE) + .param(INCLUDE_RUNTIME, true) + .build(); + return dispatcher.execute(operation) + .then(result -> Promise.resolve(asNamedNodes(result.asPropertyList()))); + }, + Ids.UNDERTOW_RUNTIME_MODCLUSTER, + Ids.UNDERTOW_RUNTIME_MODCLUSTER_BALANCER)) .itemRenderer(item -> new ItemDisplay() { @Override public String getId() { diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerNodeContextColumn.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerNodeContextColumn.java index a9bcf9cebc..02a1abfc66 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerNodeContextColumn.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/undertow/ModclusterBalancerNodeContextColumn.java @@ -15,14 +15,12 @@ */ package org.jboss.hal.client.runtime.subsystem.undertow; -import java.util.Iterator; - import javax.inject.Inject; import org.jboss.hal.core.finder.ColumnActionFactory; +import org.jboss.hal.core.finder.DependentItemsProvider; import org.jboss.hal.core.finder.Finder; import org.jboss.hal.core.finder.FinderColumn; -import org.jboss.hal.core.finder.FinderSegment; import org.jboss.hal.core.finder.ItemDisplay; import org.jboss.hal.dmr.NamedNode; import org.jboss.hal.dmr.Operation; @@ -45,7 +43,6 @@ import static org.jboss.hal.dmr.ModelDescriptionConstants.READ_CHILDREN_RESOURCES_OPERATION; import static org.jboss.hal.dmr.ModelDescriptionConstants.UNDERTOW; import static org.jboss.hal.dmr.ModelNodeHelper.asNamedNodes; -import static org.jboss.hal.resources.Strings.substringAfterLast; @AsyncColumn(Ids.UNDERTOW_RUNTIME_MODCLUSTER_BALANCER_NODE_CONTEXT) public class ModclusterBalancerNodeContextColumn extends FinderColumn { @@ -58,32 +55,21 @@ public ModclusterBalancerNodeContextColumn(Finder finder, super(new Builder(finder, Ids.UNDERTOW_RUNTIME_MODCLUSTER_BALANCER_NODE_CONTEXT, Names.CONTEXT) .columnAction(columnActionFactory.refresh(Ids.UNDERTOW_MODCLUSTER_BALANCER_NODE_CONTEXT_REFRESH)) - .itemsProvider(context -> { - String modcluster = ""; - String balancer = ""; - String node = ""; - for (Iterator> iter = context.getPath().iterator(); iter.hasNext();) { - FinderSegment finderSegment = iter.next(); - if ("undertow-runtime-modcluster".equals(finderSegment.getColumnId())) { - modcluster = substringAfterLast(finderSegment.getItemId(), "undertow-modcluster-"); - } - if ("undertow-runtime-modcluster-balancer".equals(finderSegment.getColumnId())) { - balancer = substringAfterLast(finderSegment.getItemId(), "undertow-modcluster-balancer-"); - } - if ("undertow-runtime-modcluster-balancer-node".equals(finderSegment.getColumnId())) { - node = substringAfterLast(finderSegment.getItemId(), "undertow-modcluster-balancer-node-"); - } - } - ResourceAddress address = MODCLUSTER_BALANCER_NODE_TEMPLATE.resolve(statementContext, modcluster, - balancer, node); - Operation operation = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) - .param(CHILD_TYPE, CONTEXT) - .param(INCLUDE_RUNTIME, true) - .build(); + .itemsProvider(new DependentItemsProvider( + parentNames -> { + ResourceAddress address = MODCLUSTER_BALANCER_NODE_TEMPLATE.resolve(statementContext, + parentNames); + Operation operation = new Operation.Builder(address, READ_CHILDREN_RESOURCES_OPERATION) + .param(CHILD_TYPE, CONTEXT) + .param(INCLUDE_RUNTIME, true) + .build(); - return dispatcher.execute(operation) - .then(result -> Promise.resolve(asNamedNodes(result.asPropertyList()))); - }) + return dispatcher.execute(operation) + .then(result -> Promise.resolve(asNamedNodes(result.asPropertyList()))); + }, + "undertow-runtime-modcluster", + "undertow-runtime-modcluster-balancer", + "undertow-runtime-modcluster-balancer-node")) .itemRenderer(item -> new ItemDisplay() { @Override public String getId() { diff --git a/core/src/main/java/org/jboss/hal/core/finder/DependentItemsProvider.java b/core/src/main/java/org/jboss/hal/core/finder/DependentItemsProvider.java new file mode 100644 index 0000000000..4b9616b3cb --- /dev/null +++ b/core/src/main/java/org/jboss/hal/core/finder/DependentItemsProvider.java @@ -0,0 +1,96 @@ +/* + * Copyright 2022 Red Hat + * + * 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 + * + * https://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.jboss.hal.core.finder; + +import java.util.Collections; +import java.util.List; +import java.util.function.Function; + +import elemental2.promise.Promise; + +/** ItemsProvider that requires resource name(s) to be retrieved from parent column(s) */ +public final class DependentItemsProvider implements ItemsProvider { + + private final Function>> retrieveItems; + private final ParentResolver[] parentResolvers; + private String[] parentNames; + + public DependentItemsProvider(Function>> retrieveItems, String... parentColumnIds) { + this.retrieveItems = retrieveItems; + this.parentResolvers = new ParentResolver[parentColumnIds.length]; + for (int i = 0; i < parentResolvers.length; i++) { + parentResolvers[i] = new ParentResolver(parentColumnIds[i]); + } + } + + private void resolve(FinderPath path) { + parentNames = new String[parentResolvers.length]; + for (int i = 0; i < parentResolvers.length; i++) { + parentResolvers[i].resolve(path); + parentNames[i] = parentResolvers[i].getName(); + } + } + + private boolean present() { + for (ParentResolver parentResolver : parentResolvers) { + if (!parentResolver.present()) { + return false; + } + } + return true; + } + + @Override + public Promise> items(FinderContext context) { + resolve(context.getPath()); + if (!present()) { + // shouldn't we throw an error if the parent column is missing? + return Promise.resolve(Collections.emptyList()); + } + return retrieveItems.apply(parentNames); + } + + public static ParentResolver resolver(String parentColumnId) { + return new ParentResolver(parentColumnId); + } + + public static ParentResolver resolver(String parentColumnId, FinderPath path) { + ParentResolver resolver = resolver(parentColumnId); + resolver.resolve(path); + return resolver; + } + + public static class ParentResolver { + private final String parentColumnId; + private FinderSegment segment; + + public ParentResolver(String parentColumnId) { + this.parentColumnId = parentColumnId; + } + + public void resolve(FinderPath path) { + segment = path.findColumn(parentColumnId); + } + + public boolean present() { + return segment != null; + } + + public String getName() { + return present() ? segment.getItemTitle() : null; + } + } +}