Skip to content

Commit

Permalink
Merge pull request #1235 from michpetrov/hal-1989
Browse files Browse the repository at this point in the history
HAL-1989: display error message when bootstrapping fails, consolidate…
  • Loading branch information
hpehl authored Nov 8, 2024
2 parents 85c9130 + 2b9a9a5 commit d972c22
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 200 deletions.
152 changes: 96 additions & 56 deletions app/src/main/java/org/jboss/hal/client/bootstrap/BootstrapFailed.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/
package org.jboss.hal.client.bootstrap;

import org.jboss.elemento.IsElement;
import org.jboss.elemento.Elements;
import org.jboss.hal.client.skeleton.StabilityBanner;
import org.jboss.hal.config.Endpoints;
import org.jboss.hal.resources.UIConstants;

Expand Down Expand Up @@ -59,20 +60,21 @@
import static org.jboss.hal.resources.CSS.row;
import static org.jboss.hal.resources.UIConstants.TARGET;

public class BootstrapFailed implements IsElement<HTMLDivElement> {
public class BootstrapFailed {

private static final String ADD_ALLOWED_ORIGIN = "/core-service=management/" +
"management-interface=http-interface" +
":list-add(name=allowed-origins,value=" + Endpoints.getBaseUrl();

private final HTMLDivElement root;

public BootstrapFailed(String error, Endpoints endpoints) {
HTMLElement errorHolder;
HTMLElement allowedOriginServer;
HTMLElement allowedOriginConfig;
private static void appendToBody(HTMLDivElement errorView) {
StabilityBanner.noStabilityLevelOffset();
document.documentElement.classList.add(bootstrapError);
Elements.removeChildrenFrom(document.body);
document.body.appendChild(errorView);
}

root = div()
private static HTMLDivElement errorView(final String heading, final String error, final HTMLElement content) {
return div()
.add(nav().css(navbar, navbarDefault, navbarFixedTop, navbarPf)
.attr(UIConstants.ROLE, "navigation")
.add(div().css(navbarHeader)
Expand All @@ -84,63 +86,101 @@ public BootstrapFailed(String error, Endpoints endpoints) {
.add(div().css(containerFluid)
.add(div().css(row)
.add(div().css(column(12, columnLg, columnMd, columnSm))
.add(h(1, "Bootstrap Error"))
.add(h(1, heading))
.add(div().css(alert, alertDanger, marginTopLarge)
.add(span().css(pfIcon(errorCircleO)))
.add(errorHolder = span()
.textContent("You don't have permission to access this page.")
.add(span()
.textContent(error)
.element()))
.add(div()
.add(p().textContent("The management console could not be loaded."))
.add(ul()
.add(li()
.add(p()
.add("Make sure the server is ")
.add(strong().textContent("up and running"))
.add(". Please check the log files for possible errors during startup.")))
.add(li()
.add(p()
.add("Verify you have ")
.add(strong().textContent("added users"))
.add(" which are able to access the admin console."))
.add(p()
.add("To add a new user execute the ")
.add(code().textContent("add-user.sh"))
.add(" script within the bin folder of your installation and enter the requested information.")))
.add(allowedOriginServer = li()
.add(p()
.add("Check that the management endpoint at ")
.add(a(endpoints.dmr())
.attr(TARGET, "_blank")
.textContent(endpoints.dmr()))
.add(" is available."))
.element())
.add(allowedOriginConfig = li()
.add(p()
.add("Make sure you've added " + Endpoints.getBaseUrl()
+ " as ")
.add(strong().textContent("allowed origin"))
.add(" and reload the server. Use one of the following CLI commands to add allowed origins:"))
.add(ul()
.add(li()
.add(p().textContent("Standalone:"))
.add(pre().textContent(
ADD_ALLOWED_ORIGIN)))
.add(li()
.add(p().textContent("Domain:"))
.add(pre().textContent(
"/host=primary" + ADD_ALLOWED_ORIGIN))))
.element()))))))
.add(content)))))
.element();
}

errorHolder.textContent = error;
public static void generalBootstrapError(final String error, Endpoints endpoints) {
HTMLElement allowedOriginServer;
HTMLElement allowedOriginConfig;

HTMLElement content = ul()
.add(li()
.add(p()
.add("Make sure the server is ")
.add(strong().textContent("up and running"))
.add(". Please check the log files for possible errors during startup.")))
.add(li()
.add(p()
.add("Verify you have ")
.add(strong().textContent("added users"))
.add(" which are able to access the admin console."))
.add(p()
.add("To add a new user execute the ")
.add(code().textContent("add-user.sh"))
.add(" script within the bin folder of your installation and enter the requested information.")))
.add(allowedOriginServer = li()
.add(p()
.add("Check that the management endpoint at ")
.add(a(endpoints.dmr())
.attr(TARGET, "_blank")
.textContent(endpoints.dmr()))
.add(" is available."))
.element())
.add(allowedOriginConfig = li()
.add(p()
.add("Make sure you've added " + Endpoints.getBaseUrl()
+ " as ")
.add(strong().textContent("allowed origin"))
.add(" and reload the server. Use one of the following CLI commands to add allowed origins:"))
.add(ul()
.add(li()
.add(p().textContent("Standalone:"))
.add(pre().textContent(
ADD_ALLOWED_ORIGIN)))
.add(li()
.add(p().textContent("Domain:"))
.add(pre().textContent(
"/host=primary" + ADD_ALLOWED_ORIGIN))))
.element())
.element();

HTMLDivElement root = errorView("Bootstrap Error", error, content);
setVisible(allowedOriginServer, !endpoints.isSameOrigin());
setVisible(allowedOriginConfig, !endpoints.isSameOrigin());
document.documentElement.classList.add(bootstrapError);
appendToBody(root);
}

@Override
public HTMLDivElement element() {
return root;
public static void rbacProviderFailed(final String error) {
HTMLElement content = ul()
.add(li()
.add(p()
.add("If you changed your access control provider to ")
.add(strong().textContent("RBAC"))
.add(", make sure that your configuration has current user mapped to one of the ")
.add(strong().textContent("RBAC roles"))
.add(", preferably with at least one in the Administrator or SuperUser role."))
.add(li()
.add(p()
.add("If you have started with one of the standard xml configurations shipped with WildFly,")
.add(" the \"$local\" user should be mapped to the \"SuperUser\" role and the \"local\" authentication scheme should be enabled. ")
.add("This should allow a user running the CLI on the same system as the WildFly process to have full administrative permissions. ")
.add("Remote CLI users and web-based admin console users will have no permissions.")))

.add(li()
.add(p()
.add("You should map at least one user besides \"$local\". ")
.add("Try to use CLI or shut the installation down and edit the xml configuration."))))
.element();

appendToBody(errorView("Access Provider Error", error, content));
}

public static void operationTimedOut(final String error) {
HTMLElement content = ul()
.add(li()
.add(p()
.add("Check the status of your domain, one or more hosts are unresponsive.")))
.element();

appendToBody(errorView("Bootstrap Error", error, content));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
import javax.inject.Inject;

import org.jboss.hal.client.bootstrap.endpoint.EndpointManager;
import org.jboss.hal.client.bootstrap.endpoint.RbacProviderFailed;
import org.jboss.hal.client.bootstrap.tasks.BootstrapTasks;
import org.jboss.hal.client.bootstrap.tasks.InitializationTasks;
import org.jboss.hal.client.bootstrap.tasks.InitializedTask;
import org.jboss.hal.config.Endpoints;
import org.jboss.hal.core.ExceptionHandler;
import org.jboss.hal.dmr.dispatch.Dispatcher.ResponseStatus;
import org.jboss.hal.flow.Flow;
Expand Down Expand Up @@ -84,13 +84,18 @@ public void onBootstrap() {
return null;
})
.catch_(error -> {
ResponseStatus responseStatus = ResponseStatus.fromStatusText(error.toString());
LoadingPanel.get().off();
String errorString = error.toString();
ResponseStatus responseStatus = ResponseStatus.fromStatusText(errorString);
if (responseStatus.notAllowed()) {
RbacProviderFailed.appendToBody(
BootstrapFailed.rbacProviderFailed(
"Status " + responseStatus.statusCode() + " - " + responseStatus.statusText());
} else if (errorString.contains("WFLYCTL0409")) {
BootstrapFailed.operationTimedOut(errorString);
} else {
BootstrapFailed.generalBootstrapError(errorString, Endpoints.INSTANCE);
}
logger.error("Bootstrap error: {}", error);
LoadingPanel.get().off();
return null;
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package org.jboss.hal.client.bootstrap;

import org.jboss.elemento.Elements;
import org.jboss.hal.client.logging.LogConfiguration;
import org.jboss.hal.config.Endpoints;
import org.jboss.hal.resources.Names;
Expand All @@ -25,8 +24,6 @@
import com.google.gwt.core.client.GWT;
import com.gwtplatform.mvp.client.PreBootstrapper;

import static elemental2.dom.DomGlobal.document;

public class HalPreBootstrapper implements PreBootstrapper {

private static final Logger logger = LoggerFactory.getLogger(HalPreBootstrapper.class);
Expand All @@ -38,10 +35,7 @@ public void onPreBootstrap() {
LoadingPanel.get().off();
String errorMessage = e != null ? e.getMessage() : Names.NOT_AVAILABLE;
logger.error("Uncaught bootstrap error: {}", errorMessage);
if (!document.body.hasChildNodes()) {
Elements.removeChildrenFrom(document.body);
document.body.appendChild(new BootstrapFailed(errorMessage, Endpoints.INSTANCE).element());
}
BootstrapFailed.generalBootstrapError(errorMessage, Endpoints.INSTANCE);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import javax.inject.Inject;

import org.jboss.elemento.Elements;
import org.jboss.hal.client.bootstrap.BootstrapFailed;
import org.jboss.hal.config.Endpoints;
import org.jboss.hal.config.keycloak.Keycloak;
Expand All @@ -35,7 +34,6 @@

import elemental2.dom.XMLHttpRequest;

import static elemental2.dom.DomGlobal.document;
import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME;
import static org.jboss.hal.dmr.ModelDescriptionConstants.URL;
import static org.jboss.hal.dmr.dispatch.Dispatcher.HttpMethod.GET;
Expand Down Expand Up @@ -130,12 +128,11 @@ private void connect(Optional<Endpoint> endpoint) {
}
break;
case 403:
RbacProviderFailed.appendToBody("Status " + status + " - " + xhr.statusText);
BootstrapFailed.rbacProviderFailed("Status " + status + " - " + xhr.statusText);
break;
case 503:
Elements.removeChildrenFrom(document.body);
document.body.appendChild(new BootstrapFailed("Status " + status + " - " + xhr.statusText,
Endpoints.INSTANCE).element());
BootstrapFailed.generalBootstrapError("Status " + status + " - " + xhr.statusText,
Endpoints.INSTANCE);
break;
default:
logger.info("Unable to serve HAL from '{}'. Please select a management interface.",
Expand All @@ -145,9 +142,7 @@ private void connect(Optional<Endpoint> endpoint) {
}
};
xhr.onerror = (event) -> {
Elements.removeChildrenFrom(document.body);
document.body.appendChild(
new BootstrapFailed("Failed connecting to a management interface", Endpoints.INSTANCE).element());
BootstrapFailed.generalBootstrapError("Failed connecting to a management interface", Endpoints.INSTANCE);
return null;
};
xhr.open(GET.name(), managementEndpoint, true);
Expand Down
Loading

0 comments on commit d972c22

Please sign in to comment.