Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.netbeans.modules.payara.tooling.data.PayaraPlatformVersionAPI;
import org.netbeans.modules.payara.common.status.AuthFailureStateListener;
import org.netbeans.modules.payara.common.status.MonitoringInitStateListener;
import org.netbeans.modules.payara.common.status.RemoteInstanceStateListener;
import org.openide.util.NbBundle;
import org.netbeans.modules.payara.tooling.data.PayaraServer;
import org.netbeans.modules.payara.tooling.data.PayaraServerStatus;
Expand Down Expand Up @@ -114,6 +115,11 @@ public static boolean monitor(final PayaraServer instance) {
PayaraStatus.addChangeListener(instance, authListener, PayaraStatus.STARTUP);
PayaraStatus.addErrorListener(instance, authListener);
}
if (instance.isRemote()) {
RemoteInstanceStateListener remoteInstanceListener
= new RemoteInstanceStateListener();
PayaraStatus.addErrorListener(instance, remoteInstanceListener);
}
try {
long startTime = System.currentTimeMillis();
long waitTime = INIT_MONITORING_TIMEOUT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,16 @@ AuthFailureStateListener.message=<html>Authorization failed while checking {0} \
status. Please provide valid administrator credentials.</html>
AuthFailureStateListener.error.exception=Exception was thrown in server status \
check.
RemoteInstanceStateListener.versionMismatch=<html>The version of the remote \
Payara server <b>{0}</b> does not match the version of the local Payara \
installation. Some features may not work correctly. Consider updating the \
server registration or aligning the server versions.</html>
RemoteInstanceStateListener.connectionFailed=<html>Could not connect to the \
administration interface of Payara server <b>{0}</b> at {1}:{2}. Please \
verify that the host name and administration port are correct in the server \
registration.</html>
RemoteInstanceStateListener.commandException=<html>Could not build the \
administration command URL for Payara server <b>{0}</b>. The configured \
host <b>{1}</b> or port <b>{2}</b> may be malformed. Please verify the \
server registration settings.</html>

Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.payara.common.status;

import org.netbeans.modules.payara.tooling.PayaraStatus;
import static org.netbeans.modules.payara.tooling.data.PayaraStatusCheck.VERSION;
import org.netbeans.modules.payara.tooling.TaskEvent;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle;
import org.netbeans.modules.payara.tooling.data.PayaraServer;
import org.netbeans.modules.payara.tooling.data.PayaraStatusTask;

/**
* Handle version mismatch and connection/URL failures in administration command
* calls during server status monitoring.
* <p/>
* Displays a warning notification to the user in three cases:
* <ul>
* <li>The version reported by a remote Payara server differs from the
* locally registered installation ({@link TaskEvent#VERSION_MISMATCH}).</li>
* <li>A connection failure occurred reaching the administration interface —
* typically caused by a wrong host name or port number configured in the
* server registration ({@link TaskEvent#CONNECTION_FAILED}).</li>
* <li>An exception was thrown while constructing the administration command —
* the configured host/port values may be malformed
* ({@link TaskEvent#CMD_EXCEPTION}).</li>
* </ul>
* <p/>
* For every Payara server instance being monitored there must be its own
* {@code RemoteInstanceStateListener} instance to avoid duplicate popups.
* <p/>
* @author Gaurav Gupta
*/
public class RemoteInstanceStateListener extends BasicStateListener {

// Class attributes //
/** Minimal delay between displaying warning popups [ms].
* <p/>
* Currently it shall not open a popup again sooner than after 60 seconds
* to avoid spamming the user during periodic status checks. */
private static final long POPUP_DELAY = 60000;

// Instance attributes //
/** Timestamp of last popup window. */
private volatile long lastTm;

// Constructors //
/**
* Constructs an instance of the remote instance state notification handler.
*/
public RemoteInstanceStateListener() {
super();
this.lastTm = 0;
}

// Methods //
/**
* Callback to notify about current server status after every check
* when enabled.
* <p/>
* Not used.
* <p/>
* @param server Payara server instance being monitored.
* @param status Current server status.
* @param task Last Payara server status check task details.
*/
@Override
public void currentState(final PayaraServer server,
final PayaraStatus status, final PayaraStatusTask task) {
// Not used.
}

/**
* Callback to notify about server status change when enabled.
* <p/>
* Not used.
* <p/>
* @param server Payara server instance being monitored.
* @param status Current server status.
* @param task Last Payara server status check task details.
*/
@Override
public void newState(final PayaraServer server,
final PayaraStatus status, final PayaraStatusTask task) {
// Not used.
}

/**
* Callback to notify about server status check failures.
* <p/>
* Shows a non-blocking warning popup on the VERSION check for:
* <ul>
* <li>{@link TaskEvent#VERSION_MISMATCH} — server version differs from
* the locally registered installation.</li>
* <li>{@link TaskEvent#CONNECTION_FAILED} — connection failed; likely caused by
* a wrong host name or administration port.</li>
* <li>{@link TaskEvent#CMD_EXCEPTION} — an exception was thrown while
* constructing the administration command; host/port may be malformed.</li>
* </ul>
* <p/>
* @param server Payara server instance being monitored.
* @param task Payara server status check task details.
*/
@Override
public void error(final PayaraServer server,
final PayaraStatusTask task) {
if (task.getType() != VERSION) {
return;
}
TaskEvent event = task.getEvent();
if (event == TaskEvent.VERSION_MISMATCH) {
showWarningNotification(server, "RemoteInstanceStateListener.versionMismatch",
server.getName());
} else if (event == TaskEvent.CONNECTION_FAILED) {
// Connection failed — wrong host or port configured for the server.
showWarningNotification(server, "RemoteInstanceStateListener.connectionFailed",
server.getName(), server.getHost(),
Integer.toString(server.getAdminPort()));
} else if (event == TaskEvent.CMD_EXCEPTION) {
// constructCommandUrl() threw a CommandException — host/port
// value may be malformed.
showWarningNotification(server, "RemoteInstanceStateListener.commandException",
server.getName(), server.getHost(),
Integer.toString(server.getAdminPort()));
}
}

/**
* Shows a non-blocking warning notification at most once per
* {@link #POPUP_DELAY} milliseconds.
* <p/>
* @param server Payara server instance (unused, for future use).
* @param bundleKey NbBundle key for the message text.
* @param args Arguments to the bundle message.
*/
private void showWarningNotification(final PayaraServer server,
final String bundleKey, final Object... args) {
long now = System.currentTimeMillis();
synchronized (this) {
if (now - lastTm < POPUP_DELAY) {
return;
}
lastTm = now;
}
String message = NbBundle.getMessage(
RemoteInstanceStateListener.class, bundleKey, args);
NotifyDescriptor nd = new NotifyDescriptor.Message(
message, NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notifyLater(nd);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ public enum TaskEvent {
/** Java VM execution failed. */
JAVA_VM_EXEC_FAILED,
/** Signals wrong proxy settings. */
BAD_GATEWAY;
BAD_GATEWAY,

/** Version returned by server does not match expected version. */
VERSION_MISMATCH,
/** Connection to the server administration interface failed. */
CONNECTION_FAILED,
/** Administration command URL could not be constructed. */
CMD_URL_FAILED;

// Class attributes //
/** A <code>String</code> representation of SUBMIT value. */
Expand Down Expand Up @@ -119,6 +126,15 @@ public enum TaskEvent {
/** A <code>String</code> representation of BAD_GATEWAY value. */
private static final String BAD_GATEWAY_STR = "BadGateway";

/** A <code>String</code> representation of VERSION_MISMATCH value. */
private static final String VERSION_MISMATCH_STR = "VersionMismatch";

/** A <code>String</code> representation of CONNECTION_FAILED value. */
private static final String CONNECTION_FAILED_STR = "ConnectionFailed";

/** A <code>String</code> representation of CMD_URL_FAILED value. */
private static final String CMD_URL_FAILED_STR = "CmdUrlFailed";

/**
* Stored <code>String</code> values for backward <code>String</code>
* conversion.
Expand Down Expand Up @@ -180,7 +196,10 @@ public String toString() {
case WRONG_JAVA_VM: return WRONG_JAVA_VM_STR;
case JAVA_VM_EXEC_FAILED: return JAVA_VM_EXEC_FAILED_STR;
case BAD_GATEWAY: return BAD_GATEWAY_STR;
// This is unrecheable. Returned null value means that some
case VERSION_MISMATCH: return VERSION_MISMATCH_STR;
case CONNECTION_FAILED: return CONNECTION_FAILED_STR;
case CMD_URL_FAILED: return CMD_URL_FAILED_STR;
// This is unreachable. Returned null value means that some
// enum value is not handled correctly.
default: return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,17 @@ public static PayaraPlatformVersionAPI getPayaraPlatformVersion(
}

/**
* Verifies if domain directory returned by version command result matches
* domain directory of provided Payara server entity.
* Verifies if version command result confirms Payara server is running.
* <p/>
* The version returned by the server must match the version of the local
* Payara installation. Both major and minor version values are compared.
* <p/>
* @param result Version command result.
* @param server Payara server entity.
* @return For local server value of <code>true</code> means that server
* major and minor version value matches values returned by version
* command and value of <code>false</code> that they differs.
* @return Value of <code>true</code> means that server major and minor
* version value matches values returned by version command and
* value of <code>false</code> that they differ or a comparison
* could not be made.
*/
public static boolean verifyResult(
final ResultString result, final PayaraServer server) {
Expand All @@ -140,6 +143,34 @@ public static boolean verifyResult(
return verifyResult;
}

/**
* Checks whether the version returned by the server is a known mismatch
* against the locally registered Payara installation.
* <p/>
* A version mismatch is reported only when both the server response and
* the local installation carry parseable version information that differs.
* When either side is unknown this method returns <code>false</code>.
* <p/>
* @param result Version command result.
* @param server Payara server entity.
* @return Value of <code>true</code> when the server responded with a
* version that is different from the locally registered version,
* or <code>false</code> when the versions match or comparison
* could not be performed.
*/
public static boolean isVersionMismatch(
final ResultString result, final PayaraServer server) {
String value = ServerUtils.getVersionString(result.getValue());
if (value != null) {
PayaraPlatformVersionAPI valueVersion = PayaraPlatformVersion.toValue(value);
PayaraPlatformVersionAPI serverVersion = server.getPlatformVersion();
if (valueVersion != null && serverVersion != null) {
return !serverVersion.equals(valueVersion);
}
}
return false;
}

// Constructors //
/**
* Constructs an instance of Payara server version command entity.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ public Result call() {
retries = 0;
} catch (ConnectException ce) {
return handleStateChange(TaskState.FAILED,
TaskEvent.EXCEPTION,
TaskEvent.CONNECTION_FAILED,
stateChangeArgs(ce.getLocalizedMessage()));
} catch (IOException ex) {
if (retries <= 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,21 @@ public void operationStateChanged(final TaskState newState,
event));
break;
}
// COMPLETED but versions do not match.
// For remote servers, accept the server as
// running (SUCCESS) but fire VERSION_MISMATCH
// so the user is notified via a warning popup.
if (job.status.getServer().isRemote()
&& taskResult != null
&& CommandVersion.isVersionMismatch(
taskResult, job.status.getServer())) {
job.version.setResult(new StatusResultVersion(
taskResult,
PayaraStatusCheckResult.SUCCESS,
TaskEvent.VERSION_MISMATCH));
notifyError = true;
break;
}
case FAILED:
job.version.setResult(new StatusResultVersion(taskResult,
PayaraStatusCheckResult.FAILED,
Expand Down
Loading