From 4032fdb05cc108b45b8c07f1695b847522c88f2f Mon Sep 17 00:00:00 2001 From: David McKnight Date: Mon, 10 Mar 2008 19:17:54 +0000 Subject: [PATCH] [220892][dstore] Backward compatibility: Server and Daemon should support old clients --- .../dstore/core/client/ClientConnection.java | 119 ++++-------------- .../eclipse/dstore/core/model/DataStore.java | 25 ++++ .../DefaultDataStoreCompatibilityHandler.java | 97 ++++++++++++++ .../model/IDataStoreCompatibilityHandler.java | 47 +++++++ .../core/server/ConnectionEstablisher.java | 10 +- 5 files changed, 203 insertions(+), 95 deletions(-) create mode 100644 rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DefaultDataStoreCompatibilityHandler.java create mode 100644 rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStoreCompatibilityHandler.java diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java index 3ce6d58c629..623e7c7a793 100644 --- a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java @@ -16,6 +16,7 @@ * David McKnight (IBM) - [218685] [dstore] Unable to connect when using SSL. * Martin Oberhuber (Wind River) - [219260][dstore][regression] Cannot connect to dstore daemon * David McKnight (IBM) [220123][dstore] Configurable timeout on irresponsiveness + * David McKnight (IBM) - [220892][dstore] Backward compatibility: Server and Daemon should support old clients *******************************************************************************/ package org.eclipse.dstore.core.client; @@ -42,6 +43,7 @@ import org.eclipse.dstore.core.model.DE; import org.eclipse.dstore.core.model.DataElement; import org.eclipse.dstore.core.model.DataStore; import org.eclipse.dstore.core.model.DataStoreAttributes; +import org.eclipse.dstore.core.model.IDataStoreCompatibilityHandler; import org.eclipse.dstore.core.model.IDataStoreConstants; import org.eclipse.dstore.core.model.ISSLProperties; import org.eclipse.dstore.core.server.ServerLauncher; @@ -107,18 +109,7 @@ public class ClientConnection private ArrayList _loaders; - private static final int HANDSHAKE_INCORRECT = 0; - private static final int HANDSHAKE_SERVER_OLDER = 1; - private static final int HANDSHAKE_CORRECT = 2; - private static final int HANDSHAKE_UNEXPECTED = 3; - private static final int HANDSHAKE_SERVER_NEWER = 4; - private static final int HANDSHAKE_SERVER_RECENT_OLDER = 5; - private static final int HANDSHAKE_SERVER_RECENT_NEWER = 6; - private static final int HANDSHAKE_TIMEOUT = 7; - - private static final int VERSION_INDEX_PROTOCOL = 0; - private static final int VERSION_INDEX_VERSION = 1; - private static final int VERSION_INDEX_MINOR = 2; + public static String INCOMPATIBLE_SERVER_UPDATE = "Incompatible DataStore."; //$NON-NLS-1$ public static String INCOMPATIBLE_CLIENT_UPDATE = "Incompatible DataStore."; //$NON-NLS-1$ public static String SERVER_OLDER = "Older DataStore Server."; //$NON-NLS-1$ @@ -204,8 +195,14 @@ public class ClientConnection _dataStore.setSSLProperties(properties); } + public void setCompatibilityHandler(IDataStoreCompatibilityHandler handler){ + _dataStore.setCompatibilityHandler(handler); + } - + public IDataStoreCompatibilityHandler getCompatibilityHandler(){ + return _dataStore.getCompatibilityHandler(); + } + /** * Specifies the loaders used to instantiate the miners * @@ -503,18 +500,18 @@ public class ClientConnection int handshakeResult = doHandShake(); switch (handshakeResult) { - case HANDSHAKE_CORRECT: + case IDataStoreCompatibilityHandler.HANDSHAKE_CORRECT: result = doConnect(ticket); break; - case HANDSHAKE_SERVER_RECENT_NEWER: + case IDataStoreCompatibilityHandler.HANDSHAKE_SERVER_RECENT_NEWER: result = doConnect(ticket); result.setMessage(CLIENT_OLDER); break; - case HANDSHAKE_SERVER_RECENT_OLDER: + case IDataStoreCompatibilityHandler.HANDSHAKE_SERVER_RECENT_OLDER: result = doConnect(ticket); result.setMessage(SERVER_OLDER); break; - case HANDSHAKE_SERVER_NEWER: + case IDataStoreCompatibilityHandler.HANDSHAKE_SERVER_NEWER: { msg = INCOMPATIBLE_CLIENT_UPDATE; msg += "\nThe server running on " //$NON-NLS-1$ @@ -524,7 +521,7 @@ public class ClientConnection + " is a newer DataStore server."; //$NON-NLS-1$ break; } - case HANDSHAKE_SERVER_OLDER: + case IDataStoreCompatibilityHandler.HANDSHAKE_SERVER_OLDER: { msg = INCOMPATIBLE_SERVER_UPDATE; msg += "\nThe server running on " //$NON-NLS-1$ @@ -534,7 +531,7 @@ public class ClientConnection + " is an older DataStore server."; //$NON-NLS-1$ break; } - case HANDSHAKE_INCORRECT: + case IDataStoreCompatibilityHandler.HANDSHAKE_INCORRECT: { msg = CANNOT_CONNECT; msg += INCOMPATIBLE_PROTOCOL; @@ -545,13 +542,13 @@ public class ClientConnection + " is not a valid DataStore server."; //$NON-NLS-1$ break; } - case HANDSHAKE_UNEXPECTED: + case IDataStoreCompatibilityHandler.HANDSHAKE_UNEXPECTED: { msg = CANNOT_CONNECT; msg += "Unexpected exception."; //$NON-NLS-1$ break; } - case HANDSHAKE_TIMEOUT: + case IDataStoreCompatibilityHandler.HANDSHAKE_TIMEOUT: { msg = CANNOT_CONNECT; msg += "Timeout waiting for socket activity."; //$NON-NLS-1$ @@ -863,86 +860,22 @@ public class ClientConnection } catch (InterruptedIOException e) { - return HANDSHAKE_TIMEOUT; + return IDataStoreCompatibilityHandler.HANDSHAKE_TIMEOUT; } _theSocket.setSoTimeout(0); - - String[] clientVersionStr = DataStoreAttributes.DATASTORE_VERSION.split("\\."); //$NON-NLS-1$ + String[] serverVersionStr = handshake.split("\\."); //$NON-NLS-1$ - - _dataStore.setServerVersion(Integer.parseInt(serverVersionStr[VERSION_INDEX_VERSION])); - _dataStore.setServerMinor(Integer.parseInt(serverVersionStr[VERSION_INDEX_MINOR])); + int serverVersion = Integer.parseInt(serverVersionStr[IDataStoreCompatibilityHandler.VERSION_INDEX_VERSION]); + _dataStore.setServerVersion(serverVersion); + _dataStore.setServerMinor(Integer.parseInt(serverVersionStr[IDataStoreCompatibilityHandler.VERSION_INDEX_MINOR])); - - if (handshake.equals(DataStoreAttributes.DATASTORE_VERSION)) - { - return HANDSHAKE_CORRECT; - } - else - { - if (handshake.startsWith(" _clientVersion) - { - // newer server - if (serverVersion - 1 == _clientVersion) - { - return HANDSHAKE_SERVER_RECENT_NEWER; - } - else - { - return HANDSHAKE_SERVER_NEWER; - } - } - else - { - // newer client - if (serverVersion + 1 == _clientVersion) - { - return HANDSHAKE_SERVER_RECENT_OLDER; - } - else if (serverVersion + 2 == _clientVersion) - { - // TODO we shouldn't be allowing this but - // wanting to see if old (non-open RSE server still works with open RSE) - return HANDSHAKE_SERVER_RECENT_OLDER; - } - else - { - return HANDSHAKE_SERVER_OLDER; - } - } - } - } - else - { - //System.out.println("handshake=" + handshake); - return HANDSHAKE_INCORRECT; - } - } - + return getCompatibilityHandler().checkCompatibility(handshake); } catch (Exception e) { - return HANDSHAKE_UNEXPECTED; + return IDataStoreCompatibilityHandler.HANDSHAKE_UNEXPECTED; } - + } public boolean isKnownStatus(String status) diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java index 6ed18d2be89..5df0f036073 100644 --- a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java @@ -141,6 +141,8 @@ public final class DataStore private ArrayList _waitingStatuses = null; private String _userPreferencesDirectory = null; + private IDataStoreCompatibilityHandler _compatibilityHandler; + private HashMap _classReqRepository; private File _cacheJar; @@ -437,6 +439,28 @@ public final class DataStore _commandHandler = commandHandler; } + /** + * Set the compatibility handler for the client. This is used when potential compatibility + * problems are run into - i.e. localDescriptorQuery fails + * @param handler the compatibilityHandler to use + */ + public void setCompatibilityHandler(IDataStoreCompatibilityHandler handler){ + _compatibilityHandler = handler; + } + + /** + * Get the compatibility handler for the client. This is used when potential compatibility + * problems are run into - i.e. localDescriptorQuery fails + * @return the compatibilityHandler + */ + public IDataStoreCompatibilityHandler getCompatibilityHandler(){ + if (_compatibilityHandler == null){ + _compatibilityHandler = new DefaultDataStoreCompatibilityHandler(this); + } + return _compatibilityHandler; + } + + /** * Sets the time the update handler sleeps in between update requests * @@ -2613,6 +2637,7 @@ public final class DataStore } } + getCompatibilityHandler().handleMissingCommand(descriptor, keyName); return null; } diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DefaultDataStoreCompatibilityHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DefaultDataStoreCompatibilityHandler.java new file mode 100644 index 00000000000..91fbdf6241a --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DefaultDataStoreCompatibilityHandler.java @@ -0,0 +1,97 @@ +/******************************************************************************** + * Copyright (c) 2008 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * David McKnight (IBM) - [220892][dstore] Backward compatibility: Server and Daemon should support old clients + ********************************************************************************/ +package org.eclipse.dstore.core.model; + + +public class DefaultDataStoreCompatibilityHandler implements + IDataStoreCompatibilityHandler { + private DataStore _dataStore; + + public DefaultDataStoreCompatibilityHandler(DataStore dataStore){ + _dataStore = dataStore; + } + + public int checkCompatibility(String handshake){ + + String[] clientVersionStr = DataStoreAttributes.DATASTORE_VERSION.split("\\."); //$NON-NLS-1$ + String[] serverVersionStr = handshake.split("\\."); //$NON-NLS-1$ + + int clientVersion = Integer.parseInt(clientVersionStr[VERSION_INDEX_VERSION]); + int serverVersion = Integer.parseInt(serverVersionStr[VERSION_INDEX_VERSION]); + + if (handshake.equals(DataStoreAttributes.DATASTORE_VERSION)) + { + return HANDSHAKE_CORRECT; + } + else + { + if (handshake.startsWith(" clientVersion) + { + // newer server + if (serverVersion - 1 == clientVersion) + { + return HANDSHAKE_SERVER_RECENT_NEWER; + } + else + { + return HANDSHAKE_SERVER_NEWER; + } + } + else + { + // newer client + if (serverVersion + 1 == clientVersion) + { + return HANDSHAKE_SERVER_RECENT_OLDER; + } + else if (serverVersion + 2 == clientVersion) + { + // TODO we shouldn't be allowing this but + // wanting to see if old (non-open RSE server still works with open RSE) + return HANDSHAKE_SERVER_RECENT_OLDER; + } + else + { + return HANDSHAKE_SERVER_OLDER; + } + } + } + } + else + { + return HANDSHAKE_INCORRECT; + } + } + } + + public void handleMissingCommand(DataElement descriptor, String keyName){ + // default does nothing in this situation + // System.out.println("missing command:"+keyName); + // System.out.println("Descriptor:"+descriptor.getName()); + } + +} diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStoreCompatibilityHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStoreCompatibilityHandler.java new file mode 100644 index 00000000000..56cbd1fda57 --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStoreCompatibilityHandler.java @@ -0,0 +1,47 @@ +/******************************************************************************** + * Copyright (c) 2008 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * David McKnight (IBM) - [220892][dstore] Backward compatibility: Server and Daemon should support old clients + ********************************************************************************/ +package org.eclipse.dstore.core.model; + + +public interface IDataStoreCompatibilityHandler { + public static final int HANDSHAKE_INCORRECT = 0; + public static final int HANDSHAKE_SERVER_OLDER = 1; + public static final int HANDSHAKE_CORRECT = 2; + public static final int HANDSHAKE_UNEXPECTED = 3; + public static final int HANDSHAKE_SERVER_NEWER = 4; + public static final int HANDSHAKE_SERVER_RECENT_OLDER = 5; + public static final int HANDSHAKE_SERVER_RECENT_NEWER = 6; + public static final int HANDSHAKE_TIMEOUT = 7; + + public static final int VERSION_INDEX_PROTOCOL = 0; + public static final int VERSION_INDEX_VERSION = 1; + public static final int VERSION_INDEX_MINOR = 2; + + /** + * Checks whether a server is compatible with the current client + * @param handshake the server handshake string in the form .. + * @return whether this is considered compatible with the client datastore version + */ + public int checkCompatibility(String handshake); + + /** + * This method is called to notify the compatibility handler that a call + * to localDescriptorQuery() failed to return a result. + * + * @param descriptor the object descriptor that the command was looked for under + * @param keyName the value of the command descriptor to look for + */ + public void handleMissingCommand(DataElement descriptor, String keyName); + +} diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/server/ConnectionEstablisher.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/server/ConnectionEstablisher.java index c6126e973d8..9baf9eaea21 100644 --- a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/server/ConnectionEstablisher.java +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/server/ConnectionEstablisher.java @@ -13,6 +13,7 @@ * * Contributors: * David McKnight (IBM) [220123][dstore] Configurable timeout on irresponsiveness + * David McKnight (IBM) [220892][dstore] Backward compatibility: Server and Daemon should support old clients *******************************************************************************/ package org.eclipse.dstore.internal.core.server; @@ -421,10 +422,15 @@ public class ConnectionEstablisher { try { - BufferedWriter bwriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), DE.ENCODING_UTF_8)); + BufferedWriter bwriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), DE.ENCODING_UTF_8)); PrintWriter writer = new PrintWriter(bwriter); - writer.println(DataStoreAttributes.DATASTORE_VERSION); + String version = DataStoreAttributes.DATASTORE_VERSION; + String preferenceVersion = System.getProperty("DSTORE_VERSION"); //$NON-NLS-1$ + if (preferenceVersion != null && preferenceVersion.length() > 0){ + version = preferenceVersion; + } + writer.println(version); writer.flush(); } catch (IOException e)