diff --git a/app/src/main/java/org/jboss/hal/client/configuration/SocketBindingGroupView.java b/app/src/main/java/org/jboss/hal/client/configuration/SocketBindingGroupView.java index fe31524089..a0380f6143 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/SocketBindingGroupView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/SocketBindingGroupView.java @@ -86,7 +86,7 @@ void init() { table -> presenter.addSocketBinding(INBOUND))) .button(mbuiContext.tableButtonFactory().remove(inboundTemplate, table -> presenter.removeSocketBinding(INBOUND, table.selectedRow().getName()))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(PORT, (cell, type, row, meta) -> row.get(PORT).asString()) .column(new InlineAction<>(Names.CLIENT_MAPPINGS, row -> presenter.showClientMappings(row))) .build(); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/SystemPropertiesView.java b/app/src/main/java/org/jboss/hal/client/configuration/SystemPropertiesView.java index 64d7d9fb36..78915c7b5b 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/SystemPropertiesView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/SystemPropertiesView.java @@ -42,7 +42,6 @@ import static org.jboss.hal.ballroom.LayoutBuilder.row; import static org.jboss.hal.client.configuration.SystemPropertiesPresenter.ROOT_TEMPLATE; import static org.jboss.hal.dmr.ModelDescriptionConstants.BOOT_TIME; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.dmr.ModelDescriptionConstants.VALUE; public class SystemPropertiesView extends HalViewImpl implements SystemPropertiesPresenter.MyView { @@ -74,7 +73,7 @@ public SystemPropertiesView(Environment environment, MetadataRegistry metadataRe .button(tableButtonFactory.remove(Names.SYSTEM_PROPERTY, ROOT_TEMPLATE, table -> table.selectedRow().getName(), () -> presenter.reload())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(VALUE); if (!environment.isStandalone()) { tb.column("boot-time"); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/distributableweb/DistributableWebView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/distributableweb/DistributableWebView.java index d2fa31f2b7..a65142fc99 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/distributableweb/DistributableWebView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/distributableweb/DistributableWebView.java @@ -165,7 +165,7 @@ void init() { SessionManagement.HOTROD.template, table -> table.selectedRow().getName(), () -> presenter.reload())) - .column("name", (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); hotRodSessionManagementAffinityElement = new AffinityElement(SessionManagement.HOTROD, mbuiContext.metadataRegistry(), mbuiContext.resources()); @@ -197,7 +197,7 @@ void init() { SessionManagement.INFINISPAN.template, table -> table.selectedRow().getName(), () -> presenter.reload())) - .column("name", (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); infinispanSessionManagementAffinityElement = new AffinityElement(SessionManagement.INFINISPAN, mbuiContext.metadataRegistry(), mbuiContext.resources()); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/ee/EEView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/ee/EEView.java index fd53190c38..0d62e281bb 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/ee/EEView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/ee/EEView.java @@ -290,7 +290,7 @@ private HTMLElement buildServicePanel(String baseId, AddressTemplate template, S Table table = new ModelNodeTable.Builder(Ids.build(baseId, Ids.TABLE), metadata) - .column(NAME, (cell, t, row, meta) -> row.getName()) + .nameColumn() .button(tableButtonFactory.add(Ids.build(baseId, Ids.ADD), type, template, (name, address) -> presenter.reload())) .button(tableButtonFactory.remove(type, template, (api) -> api.selectedRow().getName(), diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/ejb/EjbView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/ejb/EjbView.java index 38d8d10dfc..7e58a6adbb 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/ejb/EjbView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/ejb/EjbView.java @@ -69,7 +69,6 @@ import static org.jboss.hal.dmr.ModelDescriptionConstants.DEFAULT_SFSB_CACHE; import static org.jboss.hal.dmr.ModelDescriptionConstants.DEFAULT_SFSB_PASSIVATION_DISABLED_CACHE; import static org.jboss.hal.dmr.ModelDescriptionConstants.DEFAULT_SLSB_INSTANCE_POOL; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.dmr.ModelDescriptionConstants.PASSIVATION_STORE; import static org.jboss.hal.dmr.ModelDescriptionConstants.SERVICE; import static org.jboss.hal.dmr.ModelDescriptionConstants.TYPE; @@ -153,7 +152,7 @@ void init() { (name, address) -> presenter.reload())) .button(mbuiContext.tableButtonFactory().remove(Names.APPLICATION_SECURITY_DOMAIN, template, (api) -> api.selectedRow().getName(), () -> presenter.reload())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); appSecurityDomainForm = new ModelNodeForm.Builder(Ids.EJB3_APPLICATION_SECURITY_DOMAIN_FORM, @@ -209,7 +208,7 @@ void init() { .button(mbuiContext.tableButtonFactory().remove(rpTypeLabel, REMOTING_PROFILE_TEMPLATE, table -> table.selectedRow().getName(), () -> presenter.reload())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(ejbReceiverPage.makeInlineAction(), "20em") .column(httpConnectionPage.makeInlineAction(), "20em") .build(); @@ -261,7 +260,7 @@ void init() { .button(mbuiContext.tableButtonFactory().remove(RER_CHANNEL_CREATION_OPTIONS_TEMPLATE, table -> presenter.removeRerChannelCreationOptions(ccoTypeLabel, table.selectedRow().getName(), selectedRemotingProfile, selectedEjbReceiver))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .columns(TYPE, VALUE) .build(); @@ -426,7 +425,7 @@ public RemotingProfileSubpage(AddressTemplate template) { .button(mbuiContext.tableButtonFactory().remove(template, table -> presenter.removeRemotingProfileChild(label, table.selectedRow().getName(), selectedRemotingProfile, childType, template))) - .column(NAME, (cell, t, row, meta) -> row.getName()) + .nameColumn() .columns(columnNames); if (childType.equals(ER_TYPE)) { diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/HttpAuthenticationFactoryElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/HttpAuthenticationFactoryElement.java index e5a7b081e0..7af8aff28f 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/HttpAuthenticationFactoryElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/HttpAuthenticationFactoryElement.java @@ -68,7 +68,7 @@ class HttpAuthenticationFactoryElement implements IsElement, Attach metadata.getTemplate(), (n, a) -> presenter.reloadHttpAuthenticationFactories())) .button(tableButtonFactory.remove(Names.HTTP_AUTHENTICATION_FACTORY, metadata.getTemplate(), (table) -> table.selectedRow().getName(), () -> presenter.reloadHttpAuthenticationFactories())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(Names.MECHANISM_CONFIGURATIONS, this::showMechanismConfiguration), "15em") .build(); factoryForm = new ModelNodeForm.Builder(id(FORM), metadata) diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/JdbcRealmElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/JdbcRealmElement.java index e853c35c5e..bf17dfe229 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/JdbcRealmElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/JdbcRealmElement.java @@ -67,7 +67,7 @@ class JdbcRealmElement implements IsElement, Attachable, HasPresent .button(tableButtonFactory.add(metadata.getTemplate(), table -> presenter.addJdbcRealm())) .button(tableButtonFactory.remove(Names.JDBC_REALM, metadata.getTemplate(), (table) -> table.selectedRow().getName(), () -> presenter.reloadJdbcRealms())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(Names.PRINCIPAL_QUERY, this::showPrincipalQuery)) .build(); HTMLElement jdbcRealmSection = section() diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/LdapKeyStoreElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/LdapKeyStoreElement.java index cd4656678f..4c99f77669 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/LdapKeyStoreElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/LdapKeyStoreElement.java @@ -61,7 +61,7 @@ class LdapKeyStoreElement implements IsElement, Attachable, HasPres asList(DIR_CONTEXT, SEARCH_PATH), (n, a) -> presenter.reloadLdapKeyStores())) .button(tableButtonFactory.remove(Names.LDAP_KEY_STORE, metadata.getTemplate(), (table) -> table.selectedRow().getName(), () -> presenter.reloadLdapKeyStores())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); attributes = new ModelNodeForm.Builder(id(FORM), metadata) diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/LdapRealmElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/LdapRealmElement.java index 2ecb49e444..a55b726440 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/LdapRealmElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/LdapRealmElement.java @@ -68,7 +68,7 @@ public class LdapRealmElement implements IsElement, Attachable, Has .button(tableButtonFactory.add(metadata.getTemplate(), table -> presenter.addLdapRealm())) .button(tableButtonFactory.remove(Names.LDAP_REALM, metadata.getTemplate(), (table) -> table.selectedRow().getName(), () -> presenter.reloadLdapRealms())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(Names.IDENTITY_ATTRIBUTE_MAPPING, this::showIdentityAttributeMapping), "15em") .build(); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/MapperDecoderView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/MapperDecoderView.java index bf857d9452..9dc7868e84 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/MapperDecoderView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/MapperDecoderView.java @@ -50,7 +50,6 @@ import static org.jboss.hal.dmr.ModelDescriptionConstants.FROM; import static org.jboss.hal.dmr.ModelDescriptionConstants.MAPPED_ROLE_MAPPER; import static org.jboss.hal.dmr.ModelDescriptionConstants.MODULE; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.dmr.ModelDescriptionConstants.PERMISSIONS; import static org.jboss.hal.dmr.ModelDescriptionConstants.ROLE_MAP; import static org.jboss.hal.dmr.ModelDescriptionConstants.TABLE; @@ -123,7 +122,7 @@ void init() { Metadata metadata = mbuiContext.metadataRegistry().lookup(CONSTANT_PERMISSION_MAPPER_TEMPLATE); constantPermissionMapperElement = new ResourceElement.Builder(Ids.ELYTRON_CONSTANT_PERMISSION_MAPPER, CONSTANT_PERMISSION_MAPPER, metadata, mbuiContext) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .setComplexListAttribute(PERMISSIONS, asList(CLASS_NAME, MODULE), asList(CLASS_NAME, MODULE), modelNode -> build(modelNode.get(CLASS_NAME).asString(), modelNode.get(MODULE).asString())) .onCrud(() -> presenter.reload(CONSTANT_PERMISSION_MAPPER, this::updateConstantPermissionMapper)) @@ -148,7 +147,7 @@ void init() { .button(mbuiContext.tableButtonFactory().remove(title, MAPPED_ROLE_MAPPER_TEMPLATE, table -> table.selectedRow().getName(), () -> presenter.reload())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); mappedRoleMapperForm = new ModelNodeForm.Builder(build(mappedId, FORM), mappedMetadata) diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/SaslAuthenticationFactoryElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/SaslAuthenticationFactoryElement.java index c14a78040b..a928d79c92 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/SaslAuthenticationFactoryElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/SaslAuthenticationFactoryElement.java @@ -68,7 +68,7 @@ class SaslAuthenticationFactoryElement implements IsElement, Attach metadata.getTemplate(), (n, a) -> presenter.reloadSaslAuthenticationFactories())) .button(tableButtonFactory.remove(Names.SASL_AUTHENTICATION_FACTORY, metadata.getTemplate(), (table) -> table.selectedRow().getName(), () -> presenter.reloadSaslAuthenticationFactories())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(Names.MECHANISM_CONFIGURATIONS, this::showMechanismConfiguration), "15em") .build(); factoryForm = new ModelNodeForm.Builder(id(FORM), metadata) diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/SimplePermissionMapperElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/SimplePermissionMapperElement.java index ef949f65f1..2fe1e41409 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/SimplePermissionMapperElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/elytron/SimplePermissionMapperElement.java @@ -75,7 +75,7 @@ public class SimplePermissionMapperElement SIMPLE_PERMISSION_MAPPER_TEMPLATE, (name, address) -> presenter.reloadSimplePermissionMapper())) .button(tableButtonFactory.remove(Names.SIMPLE_PERMISSION_MAPPER, metadata.getTemplate(), (table) -> table.selectedRow().getName(), () -> presenter.reloadSimplePermissionMapper())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(Names.PERMISSION_MAPPINGS, this::showPermissionMappings), "15em") .build(); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/CacheViewImpl.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/CacheViewImpl.java index c246108cdd..31effc7003 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/CacheViewImpl.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/CacheViewImpl.java @@ -141,7 +141,7 @@ private void initBackups(CacheType cacheType, MetadataRegistry metadataRegistry, .button(tableButtonFactory.add(backupTemplate, table -> presenter.addBackup())) .button(tableButtonFactory.remove(backupTemplate, table -> presenter.removeBackup(table.selectedRow().getName()))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); backupForm = new ModelNodeForm.Builder(Ids.build(cacheType.baseId, BACKUPS, Ids.FORM), diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/RemoteCacheContainerView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/RemoteCacheContainerView.java index 12519aed39..482f18054d 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/RemoteCacheContainerView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/infinispan/RemoteCacheContainerView.java @@ -85,7 +85,7 @@ public RemoteCacheContainerView(MetadataRegistry metadataRegistry, TableButtonFa .button(tableButtonFactory.add(REMOTE_CLUSTER_TEMPLATE, table -> presenter.addRemoteCluster())) .button(tableButtonFactory.remove(REMOTE_CLUSTER_TEMPLATE, table -> presenter.removeRemoteCluster(table.selectedRow().getName()))) - .column(resources.constants().name(), (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(Names.SOCKET_BINDINGS, (cell, type, row, meta) -> { ModelNode socketBindings = row.get(SOCKET_BINDINGS); if (socketBindings.isDefined()) { diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jca/ThreadPoolsEditor.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jca/ThreadPoolsEditor.java index ab87d0fec6..ea2beb35c3 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jca/ThreadPoolsEditor.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jca/ThreadPoolsEditor.java @@ -79,7 +79,7 @@ class ThreadPoolsEditor implements IsElement, Attachable, HasPresen .button(tableButtonFactory.remove(WORKMANAGER_LRT_TEMPLATE, table -> presenter.removeThreadPool(workmanagerTemplate, workmanager, table.selectedRow()))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(resources.constants().type(), (cell, type, row, meta) -> row.getRunningMode()) .column(MAX_THREADS) .build(); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/AddressTemplates.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/AddressTemplates.java index 80c7ebcb99..bc1895ac20 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/AddressTemplates.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/AddressTemplates.java @@ -40,6 +40,8 @@ interface AddressTemplates { String SELECTED_CHANNEL_FORK_ADDRESS = JGROUPS_ADDRESS + "/channel={selected.channel}/fork=*"; String SELECTED_CHANNEL_FORK_PROTOCOL_ADDRESS = JGROUPS_ADDRESS + "/channel={selected.channel}/fork={selected.fork}/protocol=*"; + String AUTH_TOKEN_ADDRESS = JGROUPS_ADDRESS + "/stack=*/protocol=AUTH/token=*"; + String SELECTED_AUTH_TOKEN_ADDRESS = JGROUPS_ADDRESS + "/stack={selected.stack}/protocol=AUTH/token=*"; AddressTemplate JGROUPS_TEMPLATE = AddressTemplate.of(JGROUPS_ADDRESS); AddressTemplate STACK_TEMPLATE = AddressTemplate.of(STACK_ADDRESS); @@ -64,5 +66,7 @@ interface AddressTemplates { AddressTemplate CHANNEL_FORK_PROTOCOL_TEMPLATE = AddressTemplate.of(CHANNEL_FORK_PROTOCOL_ADDRESS); AddressTemplate SELECTED_CHANNEL_FORK_PROTOCOL_TEMPLATE = AddressTemplate.of( SELECTED_CHANNEL_FORK_PROTOCOL_ADDRESS); + AddressTemplate AUTH_TOKEN_TEMPLATE = AddressTemplate.of(AUTH_TOKEN_ADDRESS); + AddressTemplate SELECTED_AUTH_TOKEN_TEMPLATE = AddressTemplate.of(SELECTED_AUTH_TOKEN_ADDRESS); } diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ChannelElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ChannelElement.java index 16e16e6cf0..cb1bed8cc2 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ChannelElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ChannelElement.java @@ -42,7 +42,6 @@ import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.CHANNEL_FORK_PROTOCOL_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.CHANNEL_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.SELECTED_CHANNEL_FORK_PROTOCOL_TEMPLATE; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; /** Element to configure the fork resource */ class ChannelElement implements IsElement, Attachable, HasPresenter { @@ -72,7 +71,7 @@ class ChannelElement implements IsElement, Attachable, HasPresenter .button(tableButtonFactory.remove(CHANNEL_TEMPLATE, table -> presenter.removeResource(CHANNEL_TEMPLATE, table.selectedRow().getName(), Names.CHANNEL))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(Names.FORK, row -> { selectedChannel = row.getName(); presenter.showForks(row); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ChooseProtocolStep.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ChooseProtocolStep.java new file mode 100644 index 0000000000..fb5288cad1 --- /dev/null +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ChooseProtocolStep.java @@ -0,0 +1,66 @@ +/* + * 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.client.configuration.subsystem.jgroups; + +import java.util.Set; + +import org.jboss.elemento.InputType; +import org.jboss.hal.ballroom.wizard.WizardStep; +import org.jboss.hal.resources.Ids; +import org.jboss.hal.resources.Resources; +import org.jboss.hal.resources.UIConstants; + +import elemental2.dom.HTMLElement; + +import static org.jboss.elemento.Elements.div; +import static org.jboss.elemento.Elements.input; +import static org.jboss.elemento.Elements.label; +import static org.jboss.elemento.Elements.p; +import static org.jboss.elemento.Elements.span; +import static org.jboss.elemento.EventType.click; +import static org.jboss.hal.dmr.ModelDescriptionConstants.CUSTOM; +import static org.jboss.hal.resources.CSS.radio; + +class ChooseProtocolStep extends WizardStep { + + private final HTMLElement root; + + ChooseProtocolStep(Resources resources, Set protocolNames, ProtocolWizard wizard) { + super(resources.constants().chooseProtocol()); + root = div() + .add(p().textContent(resources.messages().chooseProtocol(CUSTOM))).element(); + + for (String protocolName : protocolNames) { + String name = protocolName; + if (name.equals("*")) { + name = CUSTOM; + } + root.appendChild(div().css(radio) + .add(label() + .add(input(InputType.radio) + .id(Ids.build(Ids.JGROUPS_PROTOCOL, name)) + .attr(UIConstants.NAME, Ids.JGROUPS_PROTOCOL) + .on(click, e -> wizard.setProtocol(protocolName)).element()) + .add(span().textContent(name))) + .element()); + } + } + + @Override + public HTMLElement element() { + return root; + } +} diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ForkElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ForkElement.java index 374292f3a4..d288f34a97 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ForkElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ForkElement.java @@ -39,7 +39,6 @@ import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.CHANNEL_FORK_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.SELECTED_CHANNEL_FORK_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.ChannelElement.PROTOCOL_ID; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; public class ForkElement implements IsElement, Attachable, HasPresenter { @@ -66,7 +65,7 @@ public class ForkElement implements IsElement, Attachable, HasPrese .button(tableButtonFactory.remove(CHANNEL_FORK_TEMPLATE, table -> presenter.removeResource(SELECTED_CHANNEL_FORK_TEMPLATE, table.selectedRow().getName(), Names.FORK))) - .column(NAME, (cell, t, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(Names.PROTOCOL, row -> { presenter.showChannelProtocol(row); presenter.showChannelInnerPage(PROTOCOL_ID); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/GenericElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/GenericElement.java index 04d1ab0791..0f7092769f 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/GenericElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/GenericElement.java @@ -36,7 +36,6 @@ import static org.jboss.elemento.Elements.h; import static org.jboss.elemento.Elements.p; import static org.jboss.elemento.Elements.section; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; public class GenericElement implements IsElement, Attachable, HasPresenter { @@ -57,7 +56,7 @@ public class GenericElement implements IsElement, Attachable, HasPr Ids.build(resourceId, Ids.ADD, Ids.FORM), name))) .button(tableButtonFactory.remove(template, table -> presenter.removeResource(template, table.selectedRow().getName(), name))) - .column(NAME, (cell, t, row, meta) -> row.getName()) + .nameColumn() .build(); form = new ModelNodeForm.Builder(Ids.build(resourceId, Ids.FORM), metadata) .onSave((form, changedValues) -> presenter diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/JGroupsPresenter.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/JGroupsPresenter.java index 2b0433aeac..0845d6d5c9 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/JGroupsPresenter.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/JGroupsPresenter.java @@ -15,13 +15,18 @@ */ package org.jboss.hal.client.configuration.subsystem.jgroups; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.TreeMap; import java.util.function.Consumer; +import java.util.stream.Collectors; import javax.inject.Inject; import org.jboss.hal.ballroom.LabelBuilder; +import org.jboss.hal.ballroom.autocomplete.StaticAutoComplete; import org.jboss.hal.ballroom.form.Form; import org.jboss.hal.ballroom.form.Form.FinishReset; import org.jboss.hal.ballroom.form.TextBoxItem; @@ -48,6 +53,7 @@ import org.jboss.hal.meta.Metadata; import org.jboss.hal.meta.MetadataRegistry; import org.jboss.hal.meta.StatementContext; +import org.jboss.hal.meta.description.ResourceDescription; import org.jboss.hal.meta.token.NameTokens; import org.jboss.hal.resources.Ids; import org.jboss.hal.resources.Names; @@ -62,18 +68,30 @@ import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit; import com.gwtplatform.mvp.client.proxy.ProxyPlace; +import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.AUTH_TOKEN_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.JGROUPS_TEMPLATE; +import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.PROTOCOL_TEMPLATE; +import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.SELECTED_AUTH_TOKEN_TEMPLATE; +import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.SELECTED_PROTOCOL_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.SELECTED_RELAY_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.STACK_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.TRANSPORT_TEMPLATE; import static org.jboss.hal.dmr.ModelDescriptionConstants.ADD; +import static org.jboss.hal.dmr.ModelDescriptionConstants.ADD_INDEX; import static org.jboss.hal.dmr.ModelDescriptionConstants.CHANNEL; +import static org.jboss.hal.dmr.ModelDescriptionConstants.DEPRECATED; import static org.jboss.hal.dmr.ModelDescriptionConstants.FORK; +import static org.jboss.hal.dmr.ModelDescriptionConstants.INCLUDE_SINGLETONS; import static org.jboss.hal.dmr.ModelDescriptionConstants.JGROUPS; +import static org.jboss.hal.dmr.ModelDescriptionConstants.MODULE; +import static org.jboss.hal.dmr.ModelDescriptionConstants.PROPERTIES; import static org.jboss.hal.dmr.ModelDescriptionConstants.PROTOCOL; +import static org.jboss.hal.dmr.ModelDescriptionConstants.READ_CHILDREN_TYPES_OPERATION; import static org.jboss.hal.dmr.ModelDescriptionConstants.RELAY; +import static org.jboss.hal.dmr.ModelDescriptionConstants.RESULT; import static org.jboss.hal.dmr.ModelDescriptionConstants.SOCKET_BINDING; import static org.jboss.hal.dmr.ModelDescriptionConstants.STACK; +import static org.jboss.hal.dmr.ModelDescriptionConstants.STATISTICS_ENABLED; import static org.jboss.hal.dmr.ModelDescriptionConstants.TRANSPORT; import static org.jboss.hal.dmr.ModelNodeHelper.asNamedNodes; import static org.jboss.hal.dmr.ModelNodeHelper.failSafePropertyList; @@ -93,6 +111,12 @@ public class JGroupsPresenter extends ApplicationFinderPresenter { + stackSingletons = result.step(0).get(RESULT).asList().stream() + .map(s -> { + String name = s.asString(); + if (!name.contains("=")) { + name += "=*"; + } + return metadataRegistry.lookup(STACK_TEMPLATE.append(name)); + }) + .filter(metadata -> !metadata.getDescription().has(DEPRECATED)) + .collect(Collectors.toMap(m -> m.getTemplate().lastName() + "=" + m.getTemplate().lastValue(), + m -> m, (m1, m2) -> null, TreeMap::new)); + + // AUTH has child singletons, we present them as separate AUTH options + result.step(1).get(RESULT).asList().forEach(token -> { + Metadata mdCopy = new Metadata(authMd.getTemplate(), authMd::getSecurityContext, + new ResourceDescription(authMd.getDescription()), authMd.getCapabilities()); + String tokenName = token.asString().substring(6); + + Metadata tokenMd = metadataRegistry + .lookup(AUTH_TOKEN_TEMPLATE.replaceWildcards("*", tokenName)); + mdCopy.getDescription().requestProperties().addAll(tokenMd.getDescription().requestProperties()); + stackSingletons.put(PROTOCOL_AUTH + " (" + tokenName + ")", mdCopy); + }); + stackSingletons.remove(PROTOCOL_AUTH); + }); + } + + private Set getNamesOf(String resource) { + return stackSingletons.keySet().stream() + .filter(name -> name.startsWith(resource)) + .map(name -> name.substring(resource.length() + 1)) + .collect(Collectors.toSet()); + } + + public Set getProtocolNames() { + return getNamesOf(PROTOCOL); + } + + public Set getTransportNames() { + return getNamesOf(TRANSPORT); + } + + public Metadata getAuthTokenMetadata(String token) { + return metadataRegistry.lookup(AUTH_TOKEN_TEMPLATE.replaceWildcards("*", token)); + } + @SuppressWarnings("ConstantConditions") void addStack() { Metadata metadata = metadataRegistry.lookup(STACK_TEMPLATE); @@ -254,6 +339,7 @@ void addStack() { String transportLabel = new LabelBuilder().label(TRANSPORT); TextBoxItem transportItem = new TextBoxItem(TRANSPORT, transportLabel); transportItem.setRequired(true); + transportItem.registerSuggestHandler(new StaticAutoComplete(new ArrayList<>(getTransportNames()))); String id = Ids.build(Ids.JGROUPS_STACK_CONFIG, Ids.ADD); ModelNodeForm form = new ModelNodeForm.Builder<>(id, metadata) .unboundFormItem(nameItem, 0) @@ -314,6 +400,54 @@ void showRemoteSites(NamedNode row) { // protocol resources + public Metadata getProtocolMetadata(String name) { + Metadata metadata = stackSingletons.get(PROTOCOL + "=" + name); + if (metadata == null) { + metadata = stackSingletons.get(PROTOCOL + "=*"); + } + return metadata; + } + + public void addProtocol(Set currentProtocols) { + Set availableProtocols = getProtocolNames().stream() + .filter(prot -> !currentProtocols.contains(prot) + && !((prot.startsWith(AUTH + " (") && currentProtocols.contains(AUTH)))) + .collect(Collectors.toSet()); + new ProtocolWizard(resources, availableProtocols, this::getProtocolMetadata, + (wizard, context) -> addProtocolSingleton(dispatcher, filterStatementContext, context.protocolName, + context.payload, (n, a) -> { + MessageEvent.fire(getEventBus(), + Message.success(resources.messages().addResourceSuccess(PROTOCOL, context.protocolName))); + reload(); + })) + .show(); + } + + private void addProtocolSingleton(Dispatcher dispatcher, StatementContext statementContext, String protocolName, + ModelNode payload, CrudOperations.AddCallback callback) { + if (!protocolName.startsWith(AUTH + " (")) { + crud.add(PROTOCOL, protocolName, + SELECTED_PROTOCOL_TEMPLATE.resolve(filterStatementContext, protocolName), + payload, (n, a) -> reload()); + return; + } + + List operations = new ArrayList<>(); + ModelNode protocolPayload = new ModelNode(); + for (String s : AUTH_ATTRIBUTES) { + if (payload.has(s)) { + ModelNode value = payload.remove(s); + protocolPayload.get(s).set(value); + } + } + final String tokenName = protocolName.substring(AUTH.length() + 2, protocolName.length() - 1); + operations.add(new Operation.Builder(SELECTED_PROTOCOL_TEMPLATE.resolve(statementContext, AUTH), ADD) + .payload(protocolPayload).build()); + operations.add(new Operation.Builder(SELECTED_AUTH_TOKEN_TEMPLATE.resolve(statementContext, tokenName), ADD) + .payload(payload).build()); + dispatcher.execute(new Composite(operations), (CompositeResult result) -> callback.execute(null, null)); + } + void showProtocols(NamedNode selectedStack) { this.selectedStack = selectedStack.getName(); getView().updateProtocols(asNamedNodes(failSafePropertyList(selectedStack, PROTOCOL))); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/JGroupsView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/JGroupsView.java index 3c874a0d55..b22ad7697a 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/JGroupsView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/JGroupsView.java @@ -141,4 +141,9 @@ public void updateChannelProtocols(List model) { channelConfig.updateProtocol(model); } + public void attach() { + super.attach(); + presenter.processStackSingletons(); + } + } diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/PropertiesStep.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/PropertiesStep.java new file mode 100644 index 0000000000..6647440220 --- /dev/null +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/PropertiesStep.java @@ -0,0 +1,75 @@ +/* + * 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.client.configuration.subsystem.jgroups; + +import org.jboss.hal.ballroom.wizard.WizardStep; +import org.jboss.hal.core.mbui.dialog.NameItem; +import org.jboss.hal.core.mbui.form.ModelNodeForm; +import org.jboss.hal.dmr.ModelNode; +import org.jboss.hal.dmr.ModelNodeHelper; +import org.jboss.hal.resources.Ids; +import org.jboss.hal.resources.Resources; + +import elemental2.dom.HTMLElement; + +import static org.jboss.elemento.Elements.div; + +class PropertiesStep extends WizardStep { + + private final HTMLElement root; + private ModelNodeForm form; + private String selectedProtocol; + private final Resources resources; + + PropertiesStep(Resources resources) { + super(resources.constants().attributes()); + this.resources = resources; + root = div().element(); + } + + @Override + public HTMLElement element() { + return root; + } + + @Override + protected void onShow(ProtocolWizard.Context context) { + if (context.protocolName.equals(selectedProtocol)) { + return; + } + selectedProtocol = context.protocolName; + + ModelNodeForm.Builder builder = new ModelNodeForm.Builder<>( + Ids.build(Ids.JGROUPS_PROTOCOL, Ids.ADD, Ids.FORM), context.protocolMetadata); + if (context.protocolName.equals("*")) { + builder.unboundFormItem(new NameItem(), 0); + } + builder.fromRequestProperties(); + + form = builder.build(); + form.attach(); + ProtocolElement.addCrValidation(resources, form, context.protocolMetadata.getDescription().requestProperties()); + root.replaceChildren(form.element()); + form.edit(new ModelNode()); + } + + @Override + protected boolean onNext(ProtocolWizard.Context context) { + boolean valid = form.save(); + context.payload = ModelNodeHelper.flatToNested(form.getModel()); + return valid; + } +} diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ProtocolElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ProtocolElement.java new file mode 100644 index 0000000000..05d517a9a3 --- /dev/null +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ProtocolElement.java @@ -0,0 +1,219 @@ +/* + * 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.client.configuration.subsystem.jgroups; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.jboss.elemento.IsElement; +import org.jboss.hal.ballroom.Attachable; +import org.jboss.hal.ballroom.LabelBuilder; +import org.jboss.hal.ballroom.Tabs; +import org.jboss.hal.ballroom.form.Form; +import org.jboss.hal.ballroom.table.ButtonHandler; +import org.jboss.hal.ballroom.table.Table; +import org.jboss.hal.core.elytron.CredentialReference; +import org.jboss.hal.core.mbui.form.ModelNodeForm; +import org.jboss.hal.core.mbui.table.ModelNodeTable; +import org.jboss.hal.core.mbui.table.TableButtonFactory; +import org.jboss.hal.core.mvp.HasPresenter; +import org.jboss.hal.dmr.ModelNode; +import org.jboss.hal.dmr.NamedNode; +import org.jboss.hal.dmr.Property; +import org.jboss.hal.meta.AddressTemplate; +import org.jboss.hal.meta.AttributeCollection; +import org.jboss.hal.meta.Metadata; +import org.jboss.hal.resources.Ids; +import org.jboss.hal.resources.Names; +import org.jboss.hal.resources.Resources; + +import com.google.common.collect.Iterables; + +import elemental2.dom.HTMLElement; + +import static org.jboss.elemento.Elements.div; +import static org.jboss.elemento.Elements.h; +import static org.jboss.elemento.Elements.p; +import static org.jboss.elemento.Elements.section; +import static org.jboss.hal.client.configuration.subsystem.jgroups.JGroupsPresenter.AUTH; +import static org.jboss.hal.dmr.ModelDescriptionConstants.TOKEN; + +public class ProtocolElement implements IsElement, Attachable, HasPresenter { + + protected final Table table; + protected final Resources resources; + private final String resourceName; + private final String resourceId; + private Form form; + private Form tokenForm; + protected JGroupsPresenter presenter; + private HTMLElement section; + private HTMLElement formContainer; + private final AddressTemplate template; + private String currentProtocolName; + + ProtocolElement(Metadata metadata, TableButtonFactory tableButtonFactory, + Resources resources, + AddressTemplate template, String resourceName, String resourceId) { + this.resources = resources; + this.template = template; + this.resourceName = resourceName; + this.resourceId = resourceId; + + ButtonHandler launchWizard = (Table table) -> { + Set current = table.getRows().stream() + .map(NamedNode::getName) + .collect(Collectors.toSet()); + presenter.addProtocol(current); + }; + + table = new ModelNodeTable.Builder(Ids.build(resourceId, Ids.TABLE), metadata) + .button(tableButtonFactory.add(template, launchWizard)) + .button(tableButtonFactory.remove(template, + table -> presenter.removeResource(template, table.selectedRow().getName(), resourceName))) + .indexColumn() + .nameColumn() + .build(); + form = createForm(metadata); + + section = section() + .add(h(1).textContent(resourceName)) + .add(p().textContent(metadata.getDescription().getDescription())) + .add(table) + .add(formContainer = div().add(form).element()).element(); + } + + @Override + public HTMLElement element() { + return section; + } + + @Override + @SuppressWarnings("ConstantConditions") + public void attach() { + table.attach(); + form.attach(); + + // we cannot use table.bind since the form might be changing + table.onSelectionChange(table -> { + if (table.hasSelection()) { + adjustAndView(table.selectedRow()); + } else { + form.clear(); + } + }); + } + + @Override + public void detach() { + form.detach(); + table.detach(); + } + + @Override + public void setPresenter(JGroupsPresenter presenter) { + this.presenter = presenter; + } + + void update(List models) { + table.update(models); + form.clear(); + table.enableButton(1, !models.isEmpty()); + } + + private void adjustAndView(NamedNode selectedRow) { + String protocolName = selectedRow.getName(); + String metadataName = protocolName; + String token = null; + if (protocolName.equals(AUTH)) { + token = selectedRow.get(TOKEN).asProperty().getName(); + metadataName = AUTH + " (" + token + ")"; + } + Metadata metadata = presenter.getProtocolMetadata(metadataName); + Set attributeNames = metadata.getDescription().attributes().stream() + .map(Property::getName).collect(Collectors.toSet()); + + // most protocols have the same attributes -> form doesn't need replacing + if (attributeNames.size() == Iterables.size(form.getFormItems()) && + !Iterables.any(form.getFormItems(), item -> !attributeNames.contains(item.getName())) && + !(AUTH.equals(protocolName)) || (AUTH.equals(currentProtocolName))) { + currentProtocolName = protocolName; + form.view(selectedRow); + return; + } + + form.detach(); + if (protocolName.equals(AUTH) && tokenForm != null) { + tokenForm.detach(); + } + + currentProtocolName = protocolName; + form = createForm(metadata); + + HTMLElement formElement; + + if (protocolName.equals(AUTH)) { + String tokenType = new LabelBuilder().label(TOKEN + ": " + token); + Metadata tokenMetadata = presenter.getAuthTokenMetadata(token); + AddressTemplate tokenTemplate = template.append(TOKEN + "=" + token); + Tabs tabs = new Tabs(Ids.build(resourceName, Ids.TAB_CONTAINER)); + tabs.add(Ids.TAB, Names.PROTOCOL, form.element()); + + tokenForm = new ModelNodeForm.Builder<>(Ids.build(resourceName, TOKEN, Ids.FORM), tokenMetadata) + .onSave((form, changedValues) -> presenter + .saveResource(tokenTemplate, protocolName, changedValues, + tokenMetadata, + resources.messages().modifySingleResourceSuccess(TOKEN))) + .prepareReset( + form -> presenter.resetSingleton(tokenTemplate.replaceWildcards(protocolName), tokenType, form, + tokenMetadata)) + .build(); + + addCrValidation(resources, tokenForm, tokenMetadata.getDescription().attributes()); + tabs.add(Ids.build(TOKEN, Ids.TAB), tokenType, tokenForm.element()); + formElement = tabs.element(); + } else { + formElement = form.element(); + } + + formContainer.replaceChildren(formElement); + form.attach(); + form.view(selectedRow); + if (protocolName.equals(AUTH)) { + tokenForm.attach(); + tokenForm.view(selectedRow.get(TOKEN).get(token)); + } + } + + private Form createForm(Metadata metadata) { + return new ModelNodeForm.Builder(Ids.build(resourceId, Ids.FORM), metadata) + .onSave((form, changedValues) -> presenter + .saveResource(template, table.selectedRow().getName(), changedValues, metadata, + resources.messages().modifySingleResourceSuccess(resourceName))) + .prepareReset(form -> presenter.resetResource(template, table.selectedRow().getName(), resourceName, form, + metadata)) + .build(); + } + + protected static void addCrValidation(Resources resources, Form form, AttributeCollection attributes) { + for (Property prop : attributes) { + if (prop.getName().endsWith("reference")) { + form.addFormValidation(new CredentialReference.CrFormValuesValidation(resources, prop.getName())); + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ProtocolWizard.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ProtocolWizard.java new file mode 100644 index 0000000000..ebcaf40892 --- /dev/null +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/ProtocolWizard.java @@ -0,0 +1,72 @@ +/* + * 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.client.configuration.subsystem.jgroups; + +import java.util.Set; +import java.util.function.Function; + +import org.jboss.hal.ballroom.wizard.Wizard; +import org.jboss.hal.dmr.ModelNode; +import org.jboss.hal.meta.Metadata; +import org.jboss.hal.resources.Names; +import org.jboss.hal.resources.Resources; + +import static org.jboss.hal.client.configuration.subsystem.jgroups.ProtocolWizard.State.CHOOSE_PROTOCOL_STEP; +import static org.jboss.hal.client.configuration.subsystem.jgroups.ProtocolWizard.State.PROPERTIES_STEP; + +public class ProtocolWizard { + + private final Wizard wizard; + private final Function getProtocolMetadata; + + public ProtocolWizard(Resources resources, Set protocolNames, + Function getProtocolMetadata, + Wizard.FinishCallback callback) { + this.getProtocolMetadata = getProtocolMetadata; + + wizard = new Wizard.Builder(resources.messages().addResourceTitle(Names.PROTOCOL), + new Context()) + .onBack((context, state) -> state == PROPERTIES_STEP ? CHOOSE_PROTOCOL_STEP : null) + .onNext((context, state) -> state == CHOOSE_PROTOCOL_STEP ? PROPERTIES_STEP : null) + .onFinish(callback) + .addStep(CHOOSE_PROTOCOL_STEP, new ChooseProtocolStep(resources, protocolNames, this)) + .addStep(PROPERTIES_STEP, new PropertiesStep(resources)) + .setInitialState(protocolNames.size() > 1 ? CHOOSE_PROTOCOL_STEP : PROPERTIES_STEP) + .build(); + + setProtocol("*"); + } + + public void show() { + wizard.show(); + } + + public void setProtocol(String name) { + Context context = wizard.getContext(); + context.protocolName = name; + context.protocolMetadata = getProtocolMetadata.apply(name); + } + + static class Context { + ModelNode payload = new ModelNode(); + String protocolName; + Metadata protocolMetadata; + } + + enum State { + CHOOSE_PROTOCOL_STEP, PROPERTIES_STEP; + } +} diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/RelayElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/RelayElement.java index 7316c1eb23..56f7295a89 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/RelayElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/RelayElement.java @@ -41,7 +41,6 @@ import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.RELAY_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.SELECTED_RELAY_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.jgroups.StackElement.REMOTE_SITE_ID; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; public class RelayElement implements IsElement, Attachable, HasPresenter { @@ -61,7 +60,7 @@ public class RelayElement implements IsElement, Attachable, HasPres .button(tableButtonFactory.remove(RELAY_TEMPLATE, table -> presenter.removeResource(SELECTED_RELAY_TEMPLATE, table.selectedRow().getName(), Names.RELAY))) - .column(NAME, (cell, t, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(Names.REMOTE_SITE, row -> { presenter.showRemoteSites(row); presenter.showStackInnerPage(REMOTE_SITE_ID); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/StackElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/StackElement.java index aad6e5532e..207d98cb17 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/StackElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/jgroups/StackElement.java @@ -41,7 +41,6 @@ import static org.jboss.elemento.Elements.p; import static org.jboss.elemento.Elements.section; import static org.jboss.hal.client.configuration.subsystem.jgroups.AddressTemplates.*; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; /** Element to configure the stack resource */ class StackElement implements IsElement, Attachable, HasPresenter { @@ -60,7 +59,7 @@ class StackElement implements IsElement, Attachable, HasPresenter, Attachable, HasPresenter presenter.removeResource(STACK_TEMPLATE, table.selectedRow().getName(), Names.STACK))) - .column(NAME, (cell, t, row, meta) -> row.getName()) + .nameColumn() .column(inlineActions) .build(); @@ -111,11 +110,9 @@ class StackElement implements IsElement, Attachable, HasPresenter, Attachable, HasPresenter { + private Form transportForm; private Form threadPoolDefaultForm; - - TransportElement(MetadataRegistry metadataRegistry, TableButtonFactory tableButtonFactory, - Metadata formMetadata, Resources resources, AddressTemplate template, - String name, String resourceId) { - super(formMetadata, tableButtonFactory, resources, template, name, resourceId); - + private JGroupsPresenter presenter; + private final Tabs transportTabs; + private final HTMLElement section; + private final HTMLElement heading; + private final HTMLElement description; + private final MetadataRegistry metadataRegistry; + private final Resources resources; + private String currentTransportType; + + TransportElement(MetadataRegistry metadataRegistry, Resources resources) { + this.metadataRegistry = metadataRegistry; + this.resources = resources; + + final String threadPoolDefaultName = Names.THREAD_POOL + " Default"; Metadata threadPoolDefaultMetadata = metadataRegistry.lookup(TRANSPORT_THREAD_POOL_DEFAULT_TEMPLATE); - threadPoolDefaultForm = new ModelNodeForm.Builder<>(Ids.JGROUPS_TRANSPORT_THREADPOOL_DEFAULT_FORM, threadPoolDefaultMetadata) .onSave((form, changedValues) -> { AddressTemplate template1 = SELECTED_TRANSPORT_THREAD_POOL_TEMPLATE - .replaceWildcards(table.selectedRow().getName(), DEFAULT); + .replaceWildcards(currentTransportType, DEFAULT); presenter.saveSingleton(template1, threadPoolDefaultMetadata, changedValues, - resources.messages().modifySingleResourceSuccess(Names.THREAD_POOL + " Default")); + resources.messages().modifySingleResourceSuccess(threadPoolDefaultName)); }) .prepareReset(form -> { AddressTemplate template1 = SELECTED_TRANSPORT_THREAD_POOL_TEMPLATE - .replaceWildcards(table.selectedRow().getName(), DEFAULT); - presenter.resetSingleton(template1, Names.THREAD_POOL + " Default", form, + .replaceWildcards(currentTransportType, DEFAULT); + presenter.resetSingleton(template1, threadPoolDefaultName, form, threadPoolDefaultMetadata); }) .build(); - HTMLElement parentElement = (HTMLElement) table.element().parentNode; - // as we are reusing the GenericElement, the form is already added to the section element, then we need to - // retrieve the form element and add it to the tab - HTMLElement form1 = (HTMLElement) parentElement.lastElementChild; - // remove the element, then adds to the tab element - parentElement.removeChild(form1); - - Tabs threadPoolTabs = new Tabs(Ids.JGROUPS_TRANSPORT_THREADPOOL_TAB_CONTAINER); - threadPoolTabs.add(Ids.build("jgroups-transport", Ids.FORM), resources.constants().attributes(), form1); - threadPoolTabs.add(Ids.JGROUPS_TRANSPORT_THREADPOOL_DEFAULT_TAB, "Thread Pool Default", + transportTabs = new Tabs(Ids.JGROUPS_TRANSPORT_THREADPOOL_TAB_CONTAINER); + transportTabs.add(Ids.build("jgroups-transport", Ids.FORM, Ids.TAB), resources.constants().attributes(), + section().element()); + transportTabs.add(Ids.JGROUPS_TRANSPORT_THREADPOOL_DEFAULT_TAB, threadPoolDefaultName, threadPoolDefaultForm.element()); - parentElement.appendChild(threadPoolTabs.element()); + section = section() + .add(heading = h(1).element()) + .add(description = p().element()) + .add(transportTabs).element(); } @Override public void attach() { - super.attach(); threadPoolDefaultForm.attach(); - - table.onSelectionChange(table -> { - if (table.hasSelection()) { - NamedNode selectedTransport = table.selectedRow(); - threadPoolDefaultForm.view(selectedTransport.get(THREAD_POOL).get(DEFAULT)); - } else { - threadPoolDefaultForm.clear(); - } - }); } @Override public void detach() { - super.detach(); + if (transportForm != null) { + transportForm.detach(); + } threadPoolDefaultForm.detach(); } - @Override void update(List models) { - super.update(models); - // disable the ADD and REMOVE buttons, as the transport is a required singleton resource, but the r-r-d - // doesn't says so - // super.update enables the "remove" button if the model is not empty - table.enableButton(0, false); - table.enableButton(1, false); + if (models.isEmpty()) { + return; + } + NamedNode transport = models.get(0); + String transportType = transport.getName(); + + if (!transportType.equals(currentTransportType)) { + currentTransportType = transportType; + // metadata is at .../stack=*/transport=, the first wildcard needs to be preserved + AddressTemplate metadataTemplate = TRANSPORT_TEMPLATE.replaceWildcards("*", currentTransportType); + Metadata transportMetadata = metadataRegistry.lookup(metadataTemplate); + AddressTemplate transportTemplate = SELECTED_TRANSPORT_TEMPLATE.replaceWildcards(currentTransportType); + String fullName = Names.TRANSPORT + ": " + currentTransportType; + + transportForm = new ModelNodeForm.Builder<>(Ids.build(Ids.JGROUPS_TRANSPORT, Ids.FORM), transportMetadata) + .onSave((form, changedValues) -> { + presenter.saveSingleton(transportTemplate, transportMetadata, changedValues, + resources.messages().modifySingleResourceSuccess(fullName)); + }) + .prepareReset(form -> { + presenter.resetSingleton(transportTemplate, fullName, form, + transportMetadata); + }) + .build(); + transportForm.attach(); + + heading.textContent = fullName; + description.textContent = transportMetadata.getDescription().getDescription(); + transportTabs.setContent(0, transportForm.element()); + } + + transportForm.view(transport); + threadPoolDefaultForm.view(transport.get(THREAD_POOL).get(DEFAULT)); + } + + @Override + public HTMLElement element() { + return section; + } + + @Override + public void setPresenter(JGroupsPresenter presenter) { + this.presenter = presenter; } } diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/logging/LoggingProfileView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/logging/LoggingProfileView.java index 8e38177ca2..f7ba635050 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/logging/LoggingProfileView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/logging/LoggingProfileView.java @@ -221,7 +221,7 @@ void init() { .button(constants.remove(), table -> crud().remove(Names.JSON_FORMATTER, table.selectedRow().getName(), jsonTemplate.replaceWildcards(presenter.getLoggingProfile()), () -> presenter.reload()), Constraint.executable(jsonTemplate, REMOVE)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); jsonFormatterForm = new ModelNodeForm.Builder(Ids.build(LOGGING_PROFILE, JSON, FORMATTER, FORM), @@ -293,7 +293,7 @@ void init() { .button(constants.remove(), table -> crud().remove(Names.XML_FORMATTER, table.selectedRow().getName(), xmlTemplate.replaceWildcards(presenter.getLoggingProfile()), () -> presenter.reload()), Constraint.executable(xmlTemplate, REMOVE)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); xmlFormatterForm = new ModelNodeForm.Builder(Ids.build(LOGGING_PROFILE, XML, FORMATTER, FORM), diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/logging/LoggingView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/logging/LoggingView.java index 7f97d38130..8dd7852d99 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/logging/LoggingView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/logging/LoggingView.java @@ -138,7 +138,7 @@ void init() { JSON_FORMATTER_TEMPLATE, (name, address) -> presenter.reload())) .button(mbuiContext.tableButtonFactory().remove(jsonLabel, JSON_FORMATTER_TEMPLATE, table -> table.selectedRow().getName(), () -> presenter.reload())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); jsonFormatterForm = new ModelNodeForm.Builder(Ids.build(LOGGING, JSON, FORMATTER, FORM), @@ -200,7 +200,7 @@ void init() { XML_FORMATTER_TEMPLATE, (name, address) -> presenter.reload())) .button(mbuiContext.tableButtonFactory().remove(xmlLabel, XML_FORMATTER_TEMPLATE, table -> table.selectedRow().getName(), () -> presenter.reload())) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); xmlFormatterForm = new ModelNodeForm.Builder(Ids.build(LOGGING, XML, FORMATTER, FORM), xmlMetadata) diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ClusteringView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ClusteringView.java index a075786aa4..d7d24fc5e9 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ClusteringView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ClusteringView.java @@ -103,7 +103,7 @@ void init() { .button(mbuiContext.resources().constants().remove(), table -> presenter.remove(ServerSubResource.BRIDGE, table.selectedRow()), Scope.SELECTED, Constraint.executable(BRIDGE_TEMPLATE, REMOVE)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); bridgeForm = new ModelNodeForm.Builder(Ids.build(Ids.MESSAGING_BRIDGE, Ids.FORM), metadata) diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ConnectionView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ConnectionView.java index a897946fcb..ed61c59212 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ConnectionView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/ConnectionView.java @@ -115,7 +115,7 @@ void init() { table -> presenter.remove(ServerSubResource.POOLED_CONNECTION_FACTORY, table.selectedRow()), Scope.SELECTED, Constraint.executable(POOLED_CONNECTION_FACTORY_TEMPLATE, REMOVE)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); pooledConnectionFactoryForm = new ModelNodeForm.Builder( diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/RemoteActiveMQView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/RemoteActiveMQView.java index 5b23507aea..424d84a980 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/RemoteActiveMQView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/messaging/RemoteActiveMQView.java @@ -111,7 +111,7 @@ void init() { table.selectedRow()), Scope.SELECTED, Constraint.executable(POOLED_CONNECTION_FACTORY_TEMPLATE, REMOVE)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); pooledConnectionFactoryForm = new ModelNodeForm.Builder( diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/HttpsListenerElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/HttpsListenerElement.java index d34432d438..56bda5b05a 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/HttpsListenerElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/HttpsListenerElement.java @@ -40,7 +40,6 @@ import static org.jboss.elemento.EventType.click; import static org.jboss.hal.client.configuration.subsystem.undertow.AddressTemplates.SERVER_TEMPLATE; import static org.jboss.hal.client.configuration.subsystem.undertow.Listener.HTTPS; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.dmr.ModelDescriptionConstants.SSL_CONTEXT; import static org.jboss.hal.resources.CSS.halTableButtons; import static org.jboss.hal.resources.Ids.ENABLE_SSL; @@ -67,7 +66,7 @@ class HttpsListenerElement extends ListenerElement { .button(tableButtonFactory.add(template, table -> presenter.addListener(HTTPS))) .button(tableButtonFactory.remove(template, table -> presenter.removeListener(HTTPS, table.selectedRow().getName()))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); form = new ModelNodeForm.Builder(Ids.build(HTTPS.baseId, Ids.FORM), metadata) diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/ListenerElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/ListenerElement.java index 64283385cb..47a9360412 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/ListenerElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/ListenerElement.java @@ -37,7 +37,6 @@ import static org.jboss.elemento.Elements.p; import static org.jboss.elemento.Elements.section; import static org.jboss.hal.client.configuration.subsystem.undertow.AddressTemplates.SERVER_TEMPLATE; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; class ListenerElement implements IsElement, Attachable, HasPresenter { @@ -58,7 +57,7 @@ class ListenerElement implements IsElement, Attachable, HasPresente .button(tableButtonFactory.add(template, table -> presenter.addListener(listenerType))) .button(tableButtonFactory.remove(template, table -> presenter.removeListener(listenerType, table.selectedRow().getName()))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); form = new ModelNodeForm.Builder(Ids.build(listenerType.baseId, Ids.FORM), metadata) diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/ServerView.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/ServerView.java index 30b67f3e46..395bcd97a8 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/ServerView.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/undertow/ServerView.java @@ -65,7 +65,6 @@ import static org.jboss.hal.dmr.ModelDescriptionConstants.HANDLER; import static org.jboss.hal.dmr.ModelDescriptionConstants.HOST; import static org.jboss.hal.dmr.ModelDescriptionConstants.LOCATION; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.dmr.ModelDescriptionConstants.PRIORITY; import static org.jboss.hal.dmr.ModelDescriptionConstants.SERVLET_CONTAINER; import static org.jboss.hal.dmr.ModelNodeHelper.asNamedNodes; @@ -124,7 +123,7 @@ public ServerView(Dispatcher dispatcher, MetadataRegistry metadataRegistry, .button(tableButtonFactory.add(HOST_TEMPLATE, table -> presenter.addHost())) .button(tableButtonFactory.remove(HOST_TEMPLATE, table -> presenter.removeHost(table.selectedRow().getName()))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(inlineActions, "15em") .build(); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/ConfigElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/ConfigElement.java index bb92aae2b1..039c7d405e 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/ConfigElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/ConfigElement.java @@ -48,7 +48,6 @@ import static org.jboss.elemento.Elements.section; import static org.jboss.hal.client.configuration.subsystem.webservice.HandlerChain.POST_HANDLER_CHAIN; import static org.jboss.hal.client.configuration.subsystem.webservice.HandlerChain.PRE_HANDLER_CHAIN; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.dmr.ModelDescriptionConstants.PROPERTY; import static org.jboss.hal.dmr.ModelDescriptionConstants.VALUE; import static org.jboss.hal.dmr.ModelNodeHelper.failSafePropertyList; @@ -77,7 +76,7 @@ class ConfigElement implements IsElement, Attachable, HasPresenter< .button(tableButtonFactory.add(configType.template, table -> presenter.addConfig())) .button(tableButtonFactory.remove(configType.template, table -> presenter.removeConfig(table.selectedRow().getName()))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(inlineActions) .build(); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/HandlerChainElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/HandlerChainElement.java index 1eece8f10f..737c01ea8b 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/HandlerChainElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/HandlerChainElement.java @@ -37,7 +37,6 @@ import static org.jboss.elemento.Elements.h; import static org.jboss.elemento.Elements.section; import static org.jboss.hal.client.configuration.subsystem.webservice.AddressTemplates.HANDLER_CHAIN_TEMPLATE; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; /** Element to configure handler chains of a client or endpoint configuration. */ class HandlerChainElement implements IsElement, Attachable, HasPresenter { @@ -58,7 +57,7 @@ class HandlerChainElement implements IsElement, Attachable, HasPres .button(tableButtonFactory.add(HANDLER_CHAIN_TEMPLATE, table -> presenter.addHandlerChain())) .button(tableButtonFactory.remove(HANDLER_CHAIN_TEMPLATE, table -> presenter.removeHandlerChain(table.selectedRow().getName()))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(Names.HANDLER, row -> presenter.showHandlers(row))) .build(); diff --git a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/HandlerElement.java b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/HandlerElement.java index 216d188e73..9859b495da 100644 --- a/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/HandlerElement.java +++ b/app/src/main/java/org/jboss/hal/client/configuration/subsystem/webservice/HandlerElement.java @@ -37,7 +37,6 @@ import static org.jboss.elemento.Elements.p; import static org.jboss.elemento.Elements.section; import static org.jboss.hal.client.configuration.subsystem.webservice.AddressTemplates.HANDLER_TEMPLATE; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; /** Element to configure handlers of a handler chain. */ class HandlerElement implements IsElement, Attachable, HasPresenter { @@ -57,7 +56,7 @@ class HandlerElement implements IsElement, Attachable, HasPresenter .button(tableButtonFactory.add(HANDLER_TEMPLATE, table -> presenter.addHandler())) .button(tableButtonFactory.remove(HANDLER_TEMPLATE, table -> presenter.removeHandler(table.selectedRow().getName()))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); String formId = Ids.build(configType.baseId, "handler", Ids.FORM); diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/ElytronRealmWithIdentity.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/ElytronRealmWithIdentity.java index d9e27e81bc..dc8fa375a6 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/ElytronRealmWithIdentity.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/ElytronRealmWithIdentity.java @@ -77,7 +77,7 @@ public class ElytronRealmWithIdentity implements IsElement, Attacha .button(resources.constants().addIdentity(), table -> presenter.addIdentity(template, metadata, table.selectedRow().getName()), Constraint.executable(template, ADD_IDENTITY)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(resources.constants().editIdentity(), this::showIdentityPage)) .build(); diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/KeyStoreElement.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/KeyStoreElement.java index 202f9198cc..7fc6bd3863 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/KeyStoreElement.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/KeyStoreElement.java @@ -83,7 +83,7 @@ public class KeyStoreElement implements IsElement, Attachable { .button(new Button<>(cons.obtain(), cons.obtainCertificate(), table -> presenter.obtainCertificate(metadata, table.selectedRow().getName()), Constraint.executable(KEY_STORE_TEMPLATE, OBTAIN_CERTIFICATE))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(cons.aliases(), row -> { selectedKeystore = row.getName(); diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/RealmsView.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/RealmsView.java index e7d8256161..1d77d3a0e3 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/RealmsView.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/RealmsView.java @@ -72,7 +72,7 @@ public RealmsView(MetadataRegistry metadataRegistry, Resources resources) { .button(resources.constants().clearCache(), table -> presenter.clearCache(table.selectedRow().getName()), Constraint.executable(CACHING_REALM_TEMPLATE, CLEAR_CACHE)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); cachingRealmForm = new ModelNodeForm.Builder(Ids.build(Ids.ELYTRON, CACHING_REALM, FORM), @@ -117,7 +117,7 @@ public RealmsView(MetadataRegistry metadataRegistry, Resources resources) { Ids.build(ELYTRON_PROPERTIES_REALM, TABLE), propertiesRealmMetadata) .button(resources.constants().load(), table -> presenter.loadProperties(table.selectedRow().getName()), Constraint.executable(PROPERTIES_REALM_TEMPLATE, LOAD)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); propertiesRealmForm = new ModelNodeForm.Builder( diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/SSLView.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/SSLView.java index 6ba783ddde..633e5817d9 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/SSLView.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/SSLView.java @@ -60,7 +60,6 @@ import static org.jboss.hal.dmr.ModelDescriptionConstants.INIT; import static org.jboss.hal.dmr.ModelDescriptionConstants.KEY_MANAGER; import static org.jboss.hal.dmr.ModelDescriptionConstants.METADATA; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.dmr.ModelDescriptionConstants.READ_IDENTITY; import static org.jboss.hal.dmr.ModelDescriptionConstants.RELOAD_CERTIFICATE_REVOCATION_LIST; import static org.jboss.hal.dmr.ModelDescriptionConstants.SECURITY_DOMAIN; @@ -121,7 +120,7 @@ public SSLView(MetadataRegistry metadataRegistry, Resources resources) { table -> presenter.changeAccountKey(table.selectedRow().getName()), Constraint.executable(CERTIFICATE_AUTHORITY_ACCOUNT_TEMPLATE, CHANGE_ACCOUNT_KEY))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); caaMetadata = new PreTextItem(METADATA); @@ -147,7 +146,7 @@ public SSLView(MetadataRegistry metadataRegistry, Resources resources) { .button(resources.constants().initialize(), table -> presenter.initKeyManager(table.selectedRow().getName()), Constraint.executable(KEY_MANAGER_TEMPLATE, INIT)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); keyManagerForm = new ModelNodeForm.Builder(Ids.build(KEY_MANAGER, FORM), keyManagerMeta) @@ -169,7 +168,7 @@ public SSLView(MetadataRegistry metadataRegistry, Resources resources) { .button(resources.constants().readIdentity(), table -> presenter.readIdentity(secDomainMeta, table.selectedRow().getName()), Constraint.executable(SECURITY_DOMAIN_TEMPLATE, READ_IDENTITY)) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); securityDomainForm = new ModelNodeForm.Builder(Ids.build(SECURITY_DOMAIN, FORM), secDomainMeta) @@ -195,7 +194,7 @@ public SSLView(MetadataRegistry metadataRegistry, Resources resources) { .button(new Button<>(resources.constants().reloadCRL(), labelBuilder.label(RELOAD_CERTIFICATE_REVOCATION_LIST), table -> presenter.reloadCRL(table.selectedRow().getName()), Constraint.executable(TRUST_MANAGER_TEMPLATE, RELOAD_CERTIFICATE_REVOCATION_LIST))) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); trustManagerForm = new ModelNodeForm.Builder(Ids.build(TRUST_MANAGER, FORM), trustMeta) diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/StoreElement.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/StoreElement.java index 3cbf5b0141..c494b376e0 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/StoreElement.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/elytron/StoreElement.java @@ -44,7 +44,6 @@ import static org.jboss.elemento.Elements.section; import static org.jboss.hal.dmr.ModelDescriptionConstants.ALIAS; import static org.jboss.hal.dmr.ModelDescriptionConstants.CERTIFICATE_DETAILS; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.resources.Ids.FORM; import static org.jboss.hal.resources.Ids.PAGE; import static org.jboss.hal.resources.Ids.PAGES; @@ -71,7 +70,7 @@ private StoreElement(Builder builder) { builder.buttonsHandler.forEach(tableBuilder::button); table = tableBuilder - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .column(new InlineAction<>(builder.resources.constants().aliases(), row -> { selectedResource = row.getName(); diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/jpa/JpaView.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/jpa/JpaView.java index 6d984a0b30..979dc519fa 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/jpa/JpaView.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/jpa/JpaView.java @@ -49,7 +49,6 @@ import static org.jboss.elemento.EventType.click; import static org.jboss.hal.ballroom.LayoutBuilder.column; import static org.jboss.hal.ballroom.LayoutBuilder.row; -import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.dmr.ModelNodeHelper.asNamedNodes; import static org.jboss.hal.resources.CSS.*; @@ -179,7 +178,7 @@ private HTMLElement buildChildPanel(String baseId, AddressTemplate template, Str Table table = new ModelNodeTable.Builder( Ids.build(baseId, resource, Ids.TABLE), metadata) - .column(NAME, (cell, type, row, meta) -> row.getName()) + .nameColumn() .build(); Form form = new ModelNodeForm.Builder(Ids.build(baseId, resource, Ids.FORM), diff --git a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/microprofile/health/MicroProfileHealthView.java b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/microprofile/health/MicroProfileHealthView.java index faddbbe6da..30198328d5 100644 --- a/app/src/main/java/org/jboss/hal/client/runtime/subsystem/microprofile/health/MicroProfileHealthView.java +++ b/app/src/main/java/org/jboss/hal/client/runtime/subsystem/microprofile/health/MicroProfileHealthView.java @@ -61,7 +61,7 @@ public MicroProfileHealthView(Resources resources, MicroProfileHealthCheckResour checkTable = new ModelNodeTable.Builder<>(Ids.build(MICRO_PROFILE_HEALTH, TABLE), metadata) .button(resources.constants().refresh(), table -> presenter.reload()) - .column(resources.constants().name(), (cell, type, row, meta) -> row.get(NAME).asString()) + .nameColumn() .column(Names.STATUS, (cell, type, row, meta) -> row.get(STATUS).asString()) .build(); diff --git a/app/src/main/resources/org/jboss/hal/client/configuration/subsystem/coremanagement/CoreManagementView.mbui.xml b/app/src/main/resources/org/jboss/hal/client/configuration/subsystem/coremanagement/CoreManagementView.mbui.xml index e0226227db..8f449fec8e 100644 --- a/app/src/main/resources/org/jboss/hal/client/configuration/subsystem/coremanagement/CoreManagementView.mbui.xml +++ b/app/src/main/resources/org/jboss/hal/client/configuration/subsystem/coremanagement/CoreManagementView.mbui.xml @@ -40,6 +40,7 @@ name-resolver="${table.selectedRow().getName()}"/> + diff --git a/core/src/main/java/org/jboss/hal/core/elytron/CredentialReference.java b/core/src/main/java/org/jboss/hal/core/elytron/CredentialReference.java index 365c815cfd..f005e74695 100644 --- a/core/src/main/java/org/jboss/hal/core/elytron/CredentialReference.java +++ b/core/src/main/java/org/jboss/hal/core/elytron/CredentialReference.java @@ -312,6 +312,7 @@ public static class CrFormValuesValidation implements FormValidation private final Resources resources; private final boolean prefixed; + private final String customName; public CrFormValuesValidation(Resources resources) { this(resources, false); @@ -320,13 +321,23 @@ public CrFormValuesValidation(Resources resources) { public CrFormValuesValidation(Resources resources, boolean prefixed) { this.resources = resources; this.prefixed = prefixed; + this.customName = null; + } + + public CrFormValuesValidation(Resources resources, String customName) { + this.resources = resources; + this.prefixed = false; + this.customName = customName; } @Override public ValidationResult validate(Form form) { - FormItem storeItem = form.getFormItem(prefixed ? STORE_PREFIXED : STORE); - FormItem aliasItem = form.getFormItem(prefixed ? ALIAS_PREFIXED : ALIAS); - FormItem clearTextItem = form.getFormItem(prefixed ? CLEAR_TEXT_PREFIXED : CLEAR_TEXT); + FormItem storeItem = form + .getFormItem(prefixed ? STORE_PREFIXED : (customName != null ? customName + DOT + STORE : STORE)); + FormItem aliasItem = form + .getFormItem(prefixed ? ALIAS_PREFIXED : (customName != null ? customName + DOT + ALIAS : ALIAS)); + FormItem clearTextItem = form.getFormItem( + prefixed ? CLEAR_TEXT_PREFIXED : (customName != null ? customName + DOT + CLEAR_TEXT : CLEAR_TEXT)); if (!clearTextItem.isEmpty() && storeItem.isEmpty() && aliasItem.isEmpty()) { // clear-text only not recommended mode return ValidationResult.OK; diff --git a/core/src/main/java/org/jboss/hal/core/mbui/ResourceElement.java b/core/src/main/java/org/jboss/hal/core/mbui/ResourceElement.java index 2f35f1c360..477ae804e3 100644 --- a/core/src/main/java/org/jboss/hal/core/mbui/ResourceElement.java +++ b/core/src/main/java/org/jboss/hal/core/mbui/ResourceElement.java @@ -446,6 +446,11 @@ public Builder column(String name, Column.RenderCallback rend return this; } + public Builder nameColumn() { + tableBuilder.nameColumn(); + return this; + } + /** * Adds a complex attribute of type {@code OBJECT}. The operation checks whether the resource contains the complex * attribute. diff --git a/core/src/main/java/org/jboss/hal/core/mbui/form/ModelNodeForm.java b/core/src/main/java/org/jboss/hal/core/mbui/form/ModelNodeForm.java index 1f8dfb376c..8415ed118c 100644 --- a/core/src/main/java/org/jboss/hal/core/mbui/form/ModelNodeForm.java +++ b/core/src/main/java/org/jboss/hal/core/mbui/form/ModelNodeForm.java @@ -297,7 +297,8 @@ public void attach() { protected void prepare(State state) { super.prepare(state); - SecurityContext securityContext = metadata.getSecurityContext(); + SecurityContext securityContext = isFromRequestProperties ? metadata.forOperation(ADD).getSecurityContext() + : metadata.getSecurityContext(); switch (state) { case EMPTY: ElementGuard.processElements( diff --git a/core/src/main/java/org/jboss/hal/core/mbui/form/PropertyFilter.java b/core/src/main/java/org/jboss/hal/core/mbui/form/PropertyFilter.java index 106d61616d..d97f1f8f1d 100644 --- a/core/src/main/java/org/jboss/hal/core/mbui/form/PropertyFilter.java +++ b/core/src/main/java/org/jboss/hal/core/mbui/form/PropertyFilter.java @@ -32,8 +32,11 @@ class PropertyFilter implements Predicate { @Override public boolean test(final Property property) { Predicate filter; - Predicate required = p -> ((p.getValue().hasDefined(REQUIRED) && p.getValue().get(REQUIRED).asBoolean()) || - (p.getValue().hasDefined(NILLABLE) && !p.getValue().get(NILLABLE).asBoolean())); + // always include add-index + Predicate isAddIndex = p -> p.getName().equals(ADD_INDEX); + Predicate required = isAddIndex + .or(p -> ((p.getValue().hasDefined(REQUIRED) && p.getValue().get(REQUIRED).asBoolean()) || + (p.getValue().hasDefined(NILLABLE) && !p.getValue().get(NILLABLE).asBoolean()))); // do not include "deprecated" attributes if (builder.hideDeprecated && property.getValue().hasDefined(DEPRECATED)) { diff --git a/core/src/main/java/org/jboss/hal/core/mbui/table/ModelNodeTable.java b/core/src/main/java/org/jboss/hal/core/mbui/table/ModelNodeTable.java index 014a7a54a9..3ac7c9611f 100644 --- a/core/src/main/java/org/jboss/hal/core/mbui/table/ModelNodeTable.java +++ b/core/src/main/java/org/jboss/hal/core/mbui/table/ModelNodeTable.java @@ -18,7 +18,9 @@ import java.util.List; import java.util.function.Function; +import org.jboss.hal.ballroom.LabelBuilder; import org.jboss.hal.ballroom.table.Column; +import org.jboss.hal.ballroom.table.ColumnBuilder; import org.jboss.hal.ballroom.table.DataTable; import org.jboss.hal.ballroom.table.GenericOptionsBuilder; import org.jboss.hal.ballroom.table.Options; @@ -38,6 +40,7 @@ import com.google.common.collect.Lists; import static org.jboss.hal.ballroom.table.RefreshMode.RESET; +import static org.jboss.hal.dmr.ModelDescriptionConstants.INDEX; import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME; import static org.jboss.hal.resources.UIConstants.HASH; import static org.jboss.hal.resources.UIConstants.data; @@ -105,7 +108,9 @@ public void update(Iterable data, RefreshMode mode, Function ident private void checkIdentifier(T data) { if (data != null) { - if (data.hasDefined(NAME)) { + if (data.hasDefined(INDEX)) { + identifier = model -> model.get(INDEX).asString(); + } else if (data.hasDefined(NAME)) { identifier = model -> model.get(NAME).asString(); } identifierChecked = true; @@ -165,6 +170,19 @@ public Builder column(String attribute) { } } + public Builder indexColumn() { + column(new ColumnBuilder(INDEX, new LabelBuilder().label(INDEX), + (c, t, r, meta) -> String.valueOf(meta.row)) + .width("8rem") + .build()); + return that(); + } + + public Builder nameColumn() { + column(NAME, (c, t, row, m) -> row.get(NAME).asString()); + return that(); + } + @Override protected Builder that() { return this; diff --git a/dmr/src/main/java/org/jboss/hal/dmr/ModelDescriptionConstants.java b/dmr/src/main/java/org/jboss/hal/dmr/ModelDescriptionConstants.java index a7b314ade4..b24232d278 100644 --- a/dmr/src/main/java/org/jboss/hal/dmr/ModelDescriptionConstants.java +++ b/dmr/src/main/java/org/jboss/hal/dmr/ModelDescriptionConstants.java @@ -47,6 +47,7 @@ public interface ModelDescriptionConstants { String ADD_CONTENT = "add-content"; String ADD_IDENTITY = "add-identity"; String ADD_IDENTITY_ATTRIBUTE = "add-identity-attribute"; + String ADD_INDEX = "add-index"; String ADD_PREFIX_ROLE_MAPPER = "add-prefix-role-mapper"; String ADD_SUFFIX_ROLE_MAPPER = "add-suffix-role-mapper"; String ADDRESS = "address"; @@ -1026,6 +1027,7 @@ public interface ModelDescriptionConstants { String TIMESTAMP_COLUMN = "timestamp-column"; String TO = "to"; String TO_PROFILE = "to-profile"; + String TOKEN = "token"; String TOKEN_REALM = "token-realm"; String TOPIC_ADDRESS = "topic-address"; String TOTAL_PROCESSING_TIME = "total-processing-time"; diff --git a/resources/src/main/java/org/jboss/hal/resources/Constants.java b/resources/src/main/java/org/jboss/hal/resources/Constants.java index 00d3899135..fc47c8b8be 100644 --- a/resources/src/main/java/org/jboss/hal/resources/Constants.java +++ b/resources/src/main/java/org/jboss/hal/resources/Constants.java @@ -74,6 +74,7 @@ public interface Constants extends com.google.gwt.i18n.client.Constants { String chooseOrDragFile(); String chooseOrDragFiles(); String choosePolicy(); + String chooseProtocol(); String chooseSingleton(); String chooseStrategy(); String chooseTemplate(); diff --git a/resources/src/main/java/org/jboss/hal/resources/Messages.java b/resources/src/main/java/org/jboss/hal/resources/Messages.java index 4ca3ace3ed..b83d0e13a4 100644 --- a/resources/src/main/java/org/jboss/hal/resources/Messages.java +++ b/resources/src/main/java/org/jboss/hal/resources/Messages.java @@ -545,6 +545,7 @@ public interface Messages extends com.google.gwt.i18n.client.Messages { String bootErrors(); String cancelNonProgressingOperation(); String changeAccountKeyQuestion(String name); + String chooseProtocol(String custom); String chooseTemplate(String custom); String chooseUpdateType(String custom); String cleanPatchHistory(); diff --git a/resources/src/main/resources/org/jboss/hal/resources/Constants.properties b/resources/src/main/resources/org/jboss/hal/resources/Constants.properties index 5b9697c8f4..f1fd3afb3a 100644 --- a/resources/src/main/resources/org/jboss/hal/resources/Constants.properties +++ b/resources/src/main/resources/org/jboss/hal/resources/Constants.properties @@ -72,6 +72,7 @@ chooseIdentityPasswordTitle=Choose password type chooseOrDragFile=Choose a file or drag it here chooseOrDragFiles=Choose one or more files or drag them here. choosePolicy=Choose Policy +chooseProtocol=Choose Protocol chooseSingleton=Choose Singleton chooseStrategy=Choose Strategy chooseTemplate=Choose Template diff --git a/resources/src/main/resources/org/jboss/hal/resources/Messages.properties b/resources/src/main/resources/org/jboss/hal/resources/Messages.properties index cfb7b91934..3a84bc6f2a 100644 --- a/resources/src/main/resources/org/jboss/hal/resources/Messages.properties +++ b/resources/src/main/resources/org/jboss/hal/resources/Messages.properties @@ -63,6 +63,7 @@ changeAliasError=Failed to change alias {0} to {1}{0} successfully changed to {1} for {2}. changePrioritySuccess=The priority has been successfully changed to {0, number}. chooseContentToDeploy=Choose the content for deploying to server group {0}. +chooseProtocol=Choose one of the predefined protocols or choose "{0}" to specify your own settings. chooseReplication=Choose which role the server should take in the data replication policy: chooseServerGroupsToDeploy=Choose the server groups for deploying {0}. chooseServerGroupsToUndeploy=Choose the server groups for undeploying {0}.