package org.jboss.as.console.client.core.bootstrap.server;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.rpc.AsyncCallback;
import org.jboss.as.console.client.core.BootstrapContext;
import org.jboss.ballroom.client.widgets.window.DefaultWindow;
import org.jboss.gwt.flow.client.Control;
import org.jboss.gwt.flow.client.Function;
import static com.google.gwt.user.client.Event.ONLOAD;
import static org.jboss.as.console.client.core.ApplicationProperties.*;
/**
* Class which connects to a running JBoss management interface or triggers the selection of an arbitrary management
* interface. By default this class first tries to connect to the management interface this console was loaded from.
* If no server was found or if running dev mode, the selection is triggered by {@link BootstrapServerDialog}.
* <p/>
* <p>Please note: This class must run <em>before</em> any bootstrap steps!</p>
*
* @author Harald Pehl
* @date 02/27/2013
*/
public class BootstrapServerSetup implements Function<BootstrapContext> {
private final static String IFRAME_ID = "__console_corsAuthentication";
private Control<BootstrapContext> control;
private BootstrapContext context;
private DefaultWindow window;
private BootstrapServerDialog dialog;
@Override
public void execute(final Control<BootstrapContext> control) {
this.control = control;
this.context = control.getContext();
if (GWT.isScript()) {
// Check if the console is part of a running JBoss AS instance
final String baseUrl = getBaseUrl();
// TODO Think of a better way to check the URL. If the standalone console was served from
// http://www.acme.org/console this code would assume that it is part of a running server instance!
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, baseUrl + "console");
requestBuilder.setCallback(new RequestCallback() {
@Override
public void onResponseReceived(final Request request, final Response response) {
// Use this JBoss instance for building the URLs
int statusCode = response.getStatusCode();
if (statusCode == 0 || statusCode == 200 || statusCode == 401) // firefox returns 0
{
setUrls(baseUrl);
control.proceed();
} else {
openDialog();
}
}
@Override
public void onError(final Request request, final Throwable exception) {
// This is a 'standalone' console. Show selection dialog
openDialog();
}
});
try {
requestBuilder.send();
} catch (RequestException e) {
openDialog();
}
} else {
openDialog();
}
}
private void openDialog() {
dialog = new BootstrapServerDialog(this);
window = new DefaultWindow("Connect to Server");
window.setWidth(600);
window.setHeight(400);
window.trapWidget(dialog.getConnectPage().asWidget());
window.setGlassEnabled(true);
window.center();
dialog.getConnectPage().reset();
}
void pingServer(final BootstrapServer server, final AsyncCallback<Void> callback) {
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, server.getUrl());
requestBuilder.setCallback(new RequestCallback() {
@Override
public void onResponseReceived(final Request request, final Response response) {
if (response.getStatusCode() == 200 || response.getStatusCode() == 0) // firefox returns 0
{
callback.onSuccess(null);
} else {
callback.onFailure(new IllegalStateException(
"Server " + server.getName() + " at " + server.getUrl() + " not running!"));
}
}
@Override
public void onError(final Request request, final Throwable exception) {
callback.onFailure(new IllegalStateException(
"Server " + server.getName() + " at " + server.getUrl() + " not running!"));
}
});
try {
requestBuilder.send();
} catch (RequestException e) {
callback.onFailure(new IllegalStateException(
"Server " + server.getName() + " at " + server.getUrl() + " not running!"));
}
}
void onConfigure() {
// Changing the title is not implemented in DefaultWindow window.setTitle("Configure Server");
window.trapWidget(dialog.getConfigurePage().asWidget());
dialog.getConfigurePage().reset();
}
void onConfigureOk() {
// Changing the title is not implemented in DefaultWindow window.setTitle("Connect to Server");
window.trapWidget(dialog.getConnectPage().asWidget());
dialog.getConnectPage().reset();
}
void onConfigureCancel() {
// Changing the title is not implemented in DefaultWindow window.setTitle("Connect to Server");
window.trapWidget(dialog.getConnectPage().asWidget());
}
void onConnect(BootstrapServer server) {
window.hide();
setUrls(server.getUrl());
// Trigger authentication using a hidden iframe. This way also Safari will show the login dialog
Element iframe = Document.get().getElementById(IFRAME_ID).cast();
DOM.sinkEvents(iframe, ONLOAD);
DOM.setEventListener(iframe, new EventListener() {
@Override
public void onBrowserEvent(final Event event) {
if (DOM.eventGetType(event) == ONLOAD) {
control.proceed();
}
}
});
iframe.setAttribute("src", context.getProperty(BootstrapContext.DOMAIN_API));
}
private void setUrls(String baseUrl) {
String localBaseUrl = baseUrl;
if (!localBaseUrl.endsWith("/")) {
localBaseUrl += "/";
}
String domainApi = localBaseUrl + "management";
String deploymentApi = localBaseUrl + "management/add-content";
String logoutApi = localBaseUrl + "logout";
System.out.println("Domain API Endpoint: " + domainApi);
context.setProperty(DOMAIN_API, domainApi);
context.setProperty(DEPLOYMENT_API, deploymentApi);
context.setProperty(LOGOUT_API, logoutApi);
}
private String getBaseUrl() {
String base = GWT.getHostPageBaseURL();
String host;
String port;
String protocol = base.substring(0, base.indexOf("//") + 2);
String remainder = base.substring(base.indexOf(protocol) + protocol.length(), base.length());
int portDelim = remainder.indexOf(":");
if (portDelim != -1) {
host = remainder.substring(0, portDelim);
String portRemainder = remainder.substring(portDelim + 1, remainder.length());
if (portRemainder.contains("/")) {
port = portRemainder.substring(0, portRemainder.indexOf("/"));
} else {
port = portRemainder;
}
} else {
host = remainder.substring(0, remainder.indexOf("/"));
if ("https://".equalsIgnoreCase(protocol)) {
port = "443";
} else {
port = "80";
}
}
// default url
return protocol + host + ":" + port + "/";
}
}