From fe52c3fa23f1e858a012d7328e125e8fe9ed2b11 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Fri, 24 Nov 2023 23:58:26 +0530 Subject: [PATCH 01/22] Implemented connectionRecoveryKey --- .../ably/lib/types/ConnectionRecoveryKey.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 lib/src/main/java/io/ably/lib/types/ConnectionRecoveryKey.java diff --git a/lib/src/main/java/io/ably/lib/types/ConnectionRecoveryKey.java b/lib/src/main/java/io/ably/lib/types/ConnectionRecoveryKey.java new file mode 100644 index 000000000..c7be39f72 --- /dev/null +++ b/lib/src/main/java/io/ably/lib/types/ConnectionRecoveryKey.java @@ -0,0 +1,62 @@ +package io.ably.lib.types; + +import com.google.gson.JsonSyntaxException; + +import java.util.HashMap; +import java.util.Map; + +import io.ably.lib.util.Log; +import io.ably.lib.util.Serialisation; + +public class ConnectionRecoveryKey { + private static final String TAG = "RecoveryKey"; + + private final String connectionKey; + private final long msgSerial; + /** + * Key - channel name + *

+ * Value - channelSerial + */ + private final Map serials = new HashMap<>(); + + public ConnectionRecoveryKey(String connectionKey, long msgSerial) { + this.connectionKey = connectionKey; + this.msgSerial = msgSerial; + } + + public String getConnectionKey() { + return connectionKey; + } + + public long getMsgSerial() { + return msgSerial; + } + + public Map getSerials() { + return serials; + } + + public void setSerials(Map serials) { + this.serials.clear(); + this.serials.putAll(serials); + } + + public void addSerial(String channelName, String channelSerial) { + this.serials.put(channelName, channelSerial); + } + + public String asJson() { + return Serialisation.gson.toJson(this); + } + + public static ConnectionRecoveryKey fromJson(String json) { + try { + return Serialisation.gson.fromJson(json, ConnectionRecoveryKey.class); + } catch (JsonSyntaxException e) { + Log.e(TAG, "Cannot create recovery key from json: " + e.getMessage()); + return null; + } + } + +} From c3e75761cc3acfad2296e982bb36a6f5cd893d44 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Sat, 25 Nov 2023 00:40:21 +0530 Subject: [PATCH 02/22] Renamed file to recoverykeycontext --- ...onnectionRecoveryKey.java => RecoveryKeyContext.java} | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) rename lib/src/main/java/io/ably/lib/types/{ConnectionRecoveryKey.java => RecoveryKeyContext.java} (83%) diff --git a/lib/src/main/java/io/ably/lib/types/ConnectionRecoveryKey.java b/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java similarity index 83% rename from lib/src/main/java/io/ably/lib/types/ConnectionRecoveryKey.java rename to lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java index c7be39f72..da2398c3b 100644 --- a/lib/src/main/java/io/ably/lib/types/ConnectionRecoveryKey.java +++ b/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java @@ -8,7 +8,7 @@ import io.ably.lib.util.Log; import io.ably.lib.util.Serialisation; -public class ConnectionRecoveryKey { +public class RecoveryKeyContext { private static final String TAG = "RecoveryKey"; private final String connectionKey; @@ -20,7 +20,7 @@ public class ConnectionRecoveryKey { */ private final Map serials = new HashMap<>(); - public ConnectionRecoveryKey(String connectionKey, long msgSerial) { + public RecoveryKeyContext(String connectionKey, long msgSerial) { this.connectionKey = connectionKey; this.msgSerial = msgSerial; } @@ -50,13 +50,12 @@ public String asJson() { return Serialisation.gson.toJson(this); } - public static ConnectionRecoveryKey fromJson(String json) { + public static RecoveryKeyContext fromJson(String json) { try { - return Serialisation.gson.fromJson(json, ConnectionRecoveryKey.class); + return Serialisation.gson.fromJson(json, RecoveryKeyContext.class); } catch (JsonSyntaxException e) { Log.e(TAG, "Cannot create recovery key from json: " + e.getMessage()); return null; } } - } From 254954780ffa014edc18a315246dd201696ceb4b Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Mon, 27 Nov 2023 17:14:12 +0530 Subject: [PATCH 03/22] Added a test to check for encoded recovery key --- .../io/ably/lib/types/RecoveryKeyContext.java | 20 +++++++------- .../lib/types/RecoveryKeyContextTest.java | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java diff --git a/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java b/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java index da2398c3b..7d7e48522 100644 --- a/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java +++ b/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java @@ -9,7 +9,7 @@ import io.ably.lib.util.Serialisation; public class RecoveryKeyContext { - private static final String TAG = "RecoveryKey"; + private static final String TAG = "RecoveryKeyContext"; private final String connectionKey; private final long msgSerial; @@ -18,7 +18,7 @@ public class RecoveryKeyContext { *

* Value - channelSerial */ - private final Map serials = new HashMap<>(); + private final Map channelSerials = new HashMap<>(); public RecoveryKeyContext(String connectionKey, long msgSerial) { this.connectionKey = connectionKey; @@ -33,24 +33,24 @@ public long getMsgSerial() { return msgSerial; } - public Map getSerials() { - return serials; + public Map getChannelSerials() { + return channelSerials; } - public void setSerials(Map serials) { - this.serials.clear(); - this.serials.putAll(serials); + public void setChannelSerials(Map channelSerials) { + this.channelSerials.clear(); + this.channelSerials.putAll(channelSerials); } public void addSerial(String channelName, String channelSerial) { - this.serials.put(channelName, channelSerial); + this.channelSerials.put(channelName, channelSerial); } - public String asJson() { + public String encode() { return Serialisation.gson.toJson(this); } - public static RecoveryKeyContext fromJson(String json) { + public static RecoveryKeyContext decode(String json) { try { return Serialisation.gson.fromJson(json, RecoveryKeyContext.class); } catch (JsonSyntaxException e) { diff --git a/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java b/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java new file mode 100644 index 000000000..96a1ee2ce --- /dev/null +++ b/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java @@ -0,0 +1,27 @@ +package io.ably.lib.types; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class RecoveryKeyContextTest { + + @Test + public void should_encode_recovery_key_context_object() { + String expectedRecoveryKey = + "{\"connectionKey\":\"uniqueKey\",\"msgSerial\":1,\"channelSerials\":{\"channel1\":\"1\",\"channel2\":\"2\",\"channel3\":\"3\"}}"; + RecoveryKeyContext recoveryKey = new RecoveryKeyContext("uniqueKey", 1); + Map keys = new HashMap<>(); + keys.put("channel1", "1"); + keys.put("channel2", "2"); + keys.put("channel3", "3"); + recoveryKey.setChannelSerials(keys); + String encodedRecoveryKey = recoveryKey.encode(); + assertEquals("should be equal", expectedRecoveryKey, encodedRecoveryKey); + } + + +} From c767de20bf4378d06f82f4f62679906a2a82c4f9 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Mon, 27 Nov 2023 17:32:35 +0530 Subject: [PATCH 04/22] Added test for encoding and decoding recovery key --- .../lib/types/RecoveryKeyContextTest.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java b/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java index 96a1ee2ce..8684a8264 100644 --- a/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java +++ b/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java @@ -6,9 +6,13 @@ import java.util.Map; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; public class RecoveryKeyContextTest { + /** + * Spec: RTN16i, RTN16f, RTN16j + */ @Test public void should_encode_recovery_key_context_object() { String expectedRecoveryKey = @@ -20,8 +24,37 @@ public void should_encode_recovery_key_context_object() { keys.put("channel3", "3"); recoveryKey.setChannelSerials(keys); String encodedRecoveryKey = recoveryKey.encode(); - assertEquals("should be equal", expectedRecoveryKey, encodedRecoveryKey); + assertEquals(expectedRecoveryKey, encodedRecoveryKey); } + /** + * Spec: RTN16i, RTN16f, RTN16j + */ + @Test + public void should_decode_recoverykey_to_recoveryKeyContextObject() { + String recoveryKey = + "{\"connectionKey\":\"key2\",\"msgSerial\":5,\"channelSerials\":{\"channel1\":\"98\",\"channel2\":\"32\",\"channel3\":\"09\"}}"; + RecoveryKeyContext recoveryKeyContext = RecoveryKeyContext.decode(recoveryKey); + assertEquals("key2", recoveryKeyContext.getConnectionKey()); + assertEquals(5, recoveryKeyContext.getMsgSerial()); + Map expectedChannelSerials = new HashMap() + {{ + put("channel1", "98"); + put("channel2", "32"); + put("channel3", "09"); + }}; + assertEquals(expectedChannelSerials, recoveryKeyContext.getChannelSerials()); + } + + /** + * Spec: RTN16i, RTN16f, RTN16j + */ + @Test + public void should_return_null_recovery_context_while_decoding_faulty_recovery_key() { + String recoveryKey = + "{\"connectionKey\":\"key2\",\"msgSerial\":\"incorrectStringSerial\",\"channelSerials\":{\"channel1\":\"98\",\"channel2\":\"32\",\"channel3\":\"09\"}}"; + RecoveryKeyContext recoveryKeyContext = RecoveryKeyContext.decode(recoveryKey); + assertNull(recoveryKeyContext); + } } From 25b9cdcb68c238e82a1cf88317f4fc7a98a37da2 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Mon, 27 Nov 2023 23:37:04 +0530 Subject: [PATCH 05/22] Added channel serial to channel properties --- .../main/java/io/ably/lib/types/ChannelProperties.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/src/main/java/io/ably/lib/types/ChannelProperties.java b/lib/src/main/java/io/ably/lib/types/ChannelProperties.java index ea3094911..50a1ae989 100644 --- a/lib/src/main/java/io/ably/lib/types/ChannelProperties.java +++ b/lib/src/main/java/io/ably/lib/types/ChannelProperties.java @@ -13,5 +13,13 @@ public class ChannelProperties { */ public String attachSerial; + /** + * ChannelSerial contains the channelSerial from latest ProtocolMessage of action type + * Message/PresenceMessage received on the channel. + *

+ * Spec: CP2b, RTL15b + */ + public String channelSerial; + public ChannelProperties() {} } From a7938e3e383e99f25c8570f1c73db48cc7e545f6 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Mon, 27 Nov 2023 23:39:29 +0530 Subject: [PATCH 06/22] Added method to set channelSerials from recover option --- .../main/java/io/ably/lib/realtime/AblyRealtime.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java index 5419b83f9..f5c048df4 100644 --- a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java +++ b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java @@ -272,6 +272,18 @@ public void transferToChannels(List queuedMessa private void clear() { map.clear(); } + + protected void setChannelSerialsFromRecoverOption(HashMap serials) { + for (Map.Entry entry : serials.entrySet()) { + String channelName = entry.getKey(); + String channelSerial = entry.getValue(); + Channel channel = this.get(channelName); + if (channel != null) { + channel.properties.channelSerial = channelSerial; + } + } + } + } /******************** From 2a8bbbdc4dd21588cf192805119491f09ef2225b Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Mon, 27 Nov 2023 23:47:05 +0530 Subject: [PATCH 07/22] Added method for getting channel serials to Channels class --- lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java index f5c048df4..ea77799e3 100644 --- a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java +++ b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java @@ -284,6 +284,14 @@ protected void setChannelSerialsFromRecoverOption(HashMap serial } } + protected HashMap getChannelSerials() { + HashMap channelSerials = new HashMap<>(); + for (Channel channel : this.values()) { + channelSerials.put(channel.name, channel.properties.channelSerial); + } + return channelSerials; + } + } /******************** From 6461967656953a5d7c67c5bd05be04d29dc89963 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Tue, 28 Nov 2023 17:14:01 +0530 Subject: [PATCH 08/22] Marked recoveryKey field as deprecated --- lib/src/main/java/io/ably/lib/realtime/Connection.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/main/java/io/ably/lib/realtime/Connection.java b/lib/src/main/java/io/ably/lib/realtime/Connection.java index 473b5df4c..4e216ebf4 100644 --- a/lib/src/main/java/io/ably/lib/realtime/Connection.java +++ b/lib/src/main/java/io/ably/lib/realtime/Connection.java @@ -49,7 +49,9 @@ public class Connection extends EventEmitter * Spec: RTN16b, RTN16c + * @deprecated use createRecoveryKey method instead. */ + @Deprecated public String recoveryKey; /** From 180d68f0419f66e900d9c2e573b97b25ae77c291 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Tue, 28 Nov 2023 18:23:26 +0530 Subject: [PATCH 09/22] Added explicit method for creating a recovery key --- .../io/ably/lib/realtime/AblyRealtime.java | 29 +++++++++---------- .../java/io/ably/lib/realtime/Connection.java | 23 +++++++++++++++ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java index ea77799e3..d2ae41cae 100644 --- a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java +++ b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java @@ -272,26 +272,25 @@ public void transferToChannels(List queuedMessa private void clear() { map.clear(); } + } - protected void setChannelSerialsFromRecoverOption(HashMap serials) { - for (Map.Entry entry : serials.entrySet()) { - String channelName = entry.getKey(); - String channelSerial = entry.getValue(); - Channel channel = this.get(channelName); - if (channel != null) { - channel.properties.channelSerial = channelSerial; - } + protected void setChannelSerialsFromRecoverOption(HashMap serials) { + for (Map.Entry entry : serials.entrySet()) { + String channelName = entry.getKey(); + String channelSerial = entry.getValue(); + Channel channel = this.channels.get(channelName); + if (channel != null) { + channel.properties.channelSerial = channelSerial; } } + } - protected HashMap getChannelSerials() { - HashMap channelSerials = new HashMap<>(); - for (Channel channel : this.values()) { - channelSerials.put(channel.name, channel.properties.channelSerial); - } - return channelSerials; + protected HashMap getChannelSerials() { + HashMap channelSerials = new HashMap<>(); + for (Channel channel : this.channels.values()) { + channelSerials.put(channel.name, channel.properties.channelSerial); } - + return channelSerials; } /******************** diff --git a/lib/src/main/java/io/ably/lib/realtime/Connection.java b/lib/src/main/java/io/ably/lib/realtime/Connection.java index 4e216ebf4..96469e9e2 100644 --- a/lib/src/main/java/io/ably/lib/realtime/Connection.java +++ b/lib/src/main/java/io/ably/lib/realtime/Connection.java @@ -4,6 +4,7 @@ import io.ably.lib.transport.ConnectionManager; import io.ably.lib.types.AblyException; import io.ably.lib.types.ErrorInfo; +import io.ably.lib.types.RecoveryKeyContext; import io.ably.lib.util.EventEmitter; import io.ably.lib.util.Log; import io.ably.lib.util.PlatformAgentProvider; @@ -54,6 +55,28 @@ public class Connection extends EventEmitter From 1509938a3d288e428c7025f789f68f183e2e9a22 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Tue, 28 Nov 2023 18:30:04 +0530 Subject: [PATCH 10/22] Simplified recoveryKeyContext class --- .../java/io/ably/lib/realtime/Connection.java | 5 +---- .../io/ably/lib/types/RecoveryKeyContext.java | 17 ++--------------- .../ably/lib/types/RecoveryKeyContextTest.java | 11 +++++------ 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/Connection.java b/lib/src/main/java/io/ably/lib/realtime/Connection.java index 96469e9e2..4c4638168 100644 --- a/lib/src/main/java/io/ably/lib/realtime/Connection.java +++ b/lib/src/main/java/io/ably/lib/realtime/Connection.java @@ -71,10 +71,7 @@ public String createRecoveryKey() { return null; } - RecoveryKeyContext recoveryKey = new RecoveryKeyContext(key, serial); - recoveryKey.setChannelSerials(this.ably.getChannelSerials()); - - return recoveryKey.encode(); + return new RecoveryKeyContext(key, serial, ably.getChannelSerials()).encode(); } /** diff --git a/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java b/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java index 7d7e48522..c110c9af3 100644 --- a/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java +++ b/lib/src/main/java/io/ably/lib/types/RecoveryKeyContext.java @@ -13,16 +13,12 @@ public class RecoveryKeyContext { private final String connectionKey; private final long msgSerial; - /** - * Key - channel name - *

- * Value - channelSerial - */ private final Map channelSerials = new HashMap<>(); - public RecoveryKeyContext(String connectionKey, long msgSerial) { + public RecoveryKeyContext(String connectionKey, long msgSerial, Map channelSerials) { this.connectionKey = connectionKey; this.msgSerial = msgSerial; + this.channelSerials.putAll(channelSerials); } public String getConnectionKey() { @@ -37,15 +33,6 @@ public Map getChannelSerials() { return channelSerials; } - public void setChannelSerials(Map channelSerials) { - this.channelSerials.clear(); - this.channelSerials.putAll(channelSerials); - } - - public void addSerial(String channelName, String channelSerial) { - this.channelSerials.put(channelName, channelSerial); - } - public String encode() { return Serialisation.gson.toJson(this); } diff --git a/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java b/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java index 8684a8264..85d9e0127 100644 --- a/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java +++ b/lib/src/test/java/io/ably/lib/types/RecoveryKeyContextTest.java @@ -17,12 +17,11 @@ public class RecoveryKeyContextTest { public void should_encode_recovery_key_context_object() { String expectedRecoveryKey = "{\"connectionKey\":\"uniqueKey\",\"msgSerial\":1,\"channelSerials\":{\"channel1\":\"1\",\"channel2\":\"2\",\"channel3\":\"3\"}}"; - RecoveryKeyContext recoveryKey = new RecoveryKeyContext("uniqueKey", 1); - Map keys = new HashMap<>(); - keys.put("channel1", "1"); - keys.put("channel2", "2"); - keys.put("channel3", "3"); - recoveryKey.setChannelSerials(keys); + Map serials = new HashMap<>(); + serials.put("channel1", "1"); + serials.put("channel2", "2"); + serials.put("channel3", "3"); + RecoveryKeyContext recoveryKey = new RecoveryKeyContext("uniqueKey", 1, serials); String encodedRecoveryKey = recoveryKey.encode(); assertEquals(expectedRecoveryKey, encodedRecoveryKey); } From 169392e21440a28054d5e7f6783d437eddbb9c7f Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Tue, 28 Nov 2023 21:49:41 +0530 Subject: [PATCH 11/22] Setting recovery key and serials from clientOption --- .../io/ably/lib/realtime/AblyRealtime.java | 21 +++++++++++-------- .../java/io/ably/lib/realtime/Connection.java | 2 +- .../ably/lib/transport/ConnectionManager.java | 2 +- .../io/ably/lib/transport/ITransport.java | 20 +++++------------- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java index d2ae41cae..8e3a77035 100644 --- a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java +++ b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java @@ -9,12 +9,7 @@ import io.ably.lib.rest.AblyRest; import io.ably.lib.rest.Auth; import io.ably.lib.transport.ConnectionManager; -import io.ably.lib.types.AblyException; -import io.ably.lib.types.ChannelOptions; -import io.ably.lib.types.ClientOptions; -import io.ably.lib.types.ErrorInfo; -import io.ably.lib.types.ProtocolMessage; -import io.ably.lib.types.ReadOnlyMap; +import io.ably.lib.types.*; import io.ably.lib.util.InternalMap; import io.ably.lib.util.Log; @@ -71,6 +66,14 @@ public void onConnectionStateChanged(ConnectionStateListener.ConnectionStateChan } }); + if (options.recover != null && !options.recover.isEmpty()) { + RecoveryKeyContext recoveryKeyContext = RecoveryKeyContext.decode(options.recover); + if (recoveryKeyContext != null) { + setChannelSerialsFromRecoverOption(recoveryKeyContext.getChannelSerials()); + connection.connectionManager.msgSerial = recoveryKeyContext.getMsgSerial(); //RTN16f + } + } + if(options.autoConnect) connection.connect(); } @@ -274,7 +277,7 @@ private void clear() { } } - protected void setChannelSerialsFromRecoverOption(HashMap serials) { + protected void setChannelSerialsFromRecoverOption(Map serials) { for (Map.Entry entry : serials.entrySet()) { String channelName = entry.getKey(); String channelSerial = entry.getValue(); @@ -285,8 +288,8 @@ protected void setChannelSerialsFromRecoverOption(HashMap serial } } - protected HashMap getChannelSerials() { - HashMap channelSerials = new HashMap<>(); + protected Map getChannelSerials() { + Map channelSerials = new HashMap<>(); for (Channel channel : this.channels.values()) { channelSerials.put(channel.name, channel.properties.channelSerial); } diff --git a/lib/src/main/java/io/ably/lib/realtime/Connection.java b/lib/src/main/java/io/ably/lib/realtime/Connection.java index 4c4638168..fa342ec48 100644 --- a/lib/src/main/java/io/ably/lib/realtime/Connection.java +++ b/lib/src/main/java/io/ably/lib/realtime/Connection.java @@ -71,7 +71,7 @@ public String createRecoveryKey() { return null; } - return new RecoveryKeyContext(key, serial, ably.getChannelSerials()).encode(); + return new RecoveryKeyContext(key, connectionManager.msgSerial, ably.getChannelSerials()).encode(); } /** diff --git a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java index 29f33706a..da3cc9116 100644 --- a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java +++ b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java @@ -1905,7 +1905,7 @@ private boolean isFatalError(ErrorInfo err) { private boolean suppressRetry; /* for tests only; modified via reflection */ private ITransport transport; private long suspendTime; - private long msgSerial; + public long msgSerial; private long lastActivity; private CMConnectivityListener connectivityListener; private long connectionStateTtl = Defaults.connectionStateTtl; diff --git a/lib/src/main/java/io/ably/lib/transport/ITransport.java b/lib/src/main/java/io/ably/lib/transport/ITransport.java index 93b426f3b..9dadb54a5 100644 --- a/lib/src/main/java/io/ably/lib/transport/ITransport.java +++ b/lib/src/main/java/io/ably/lib/transport/ITransport.java @@ -1,10 +1,6 @@ package io.ably.lib.transport; -import io.ably.lib.types.AblyException; -import io.ably.lib.types.ClientOptions; -import io.ably.lib.types.ErrorInfo; -import io.ably.lib.types.Param; -import io.ably.lib.types.ProtocolMessage; +import io.ably.lib.types.*; import io.ably.lib.util.AgentHeaderCreator; import io.ably.lib.util.Log; import io.ably.lib.util.PlatformAgentProvider; @@ -14,8 +10,6 @@ import java.util.Arrays; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public interface ITransport { @@ -73,15 +67,11 @@ public Param[] getConnectParams(Param[] baseParams) { paramList.add(new Param("resume", connectionKey)); if(connectionSerial != null) paramList.add(new Param("connectionSerial", connectionSerial)); - } else if(options.recover != null) { + } else if(options.recover != null && !options.recover.isEmpty()) { // RTN16k mode = Mode.recover; - Pattern recoverSpec = Pattern.compile("^([\\w\\-\\!]+):(\\-?\\d+)$"); - Matcher match = recoverSpec.matcher(options.recover); - if(match.matches()) { - paramList.add(new Param("recover", match.group(1))); - paramList.add(new Param("connectionSerial", match.group(2))); - } else { - Log.e(TAG, "Invalid recover string specified"); + RecoveryKeyContext recoveryKeyContext = RecoveryKeyContext.decode(options.recover); + if (recoveryKeyContext != null) { + paramList.add(new Param("recover", recoveryKeyContext.getConnectionKey())); } } if(options.clientId != null) From c6af891b341ce864c67ad65114b343c6430fbe3b Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Tue, 28 Nov 2023 22:17:34 +0530 Subject: [PATCH 12/22] Refactored recoverykey to use createRecoveryKey method --- .../main/java/io/ably/lib/transport/ConnectionManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java index da3cc9116..7b18e7a9c 100644 --- a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java +++ b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java @@ -1196,7 +1196,7 @@ private void onChannelMessage(ProtocolMessage message) { if(message.connectionSerial != null) { connection.serial = message.connectionSerial.longValue(); if (connection.key != null) - connection.recoveryKey = connection.key + ":" + message.connectionSerial; + connection.recoveryKey = connection.createRecoveryKey(); } channels.onMessage(message); } @@ -1243,7 +1243,7 @@ private synchronized void onConnected(ProtocolMessage message) { if(message.connectionSerial != null) { connection.serial = message.connectionSerial; if (connection.key != null) - connection.recoveryKey = connection.key + ":" + message.connectionSerial; + connection.recoveryKey = connection.createRecoveryKey(); } ConnectionDetails connectionDetails = message.connectionDetails; From e7dc410547ecae9eddcc46c10195b21ae9b02f02 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Tue, 28 Nov 2023 22:33:40 +0530 Subject: [PATCH 13/22] Removed all connection serial references from the code --- .../java/io/ably/lib/realtime/Connection.java | 10 ---------- .../io/ably/lib/transport/ConnectionManager.java | 16 ++++------------ .../java/io/ably/lib/transport/ITransport.java | 3 --- .../java/io/ably/lib/types/ProtocolMessage.java | 4 ---- 4 files changed, 4 insertions(+), 29 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/Connection.java b/lib/src/main/java/io/ably/lib/realtime/Connection.java index fa342ec48..443aef04f 100644 --- a/lib/src/main/java/io/ably/lib/realtime/Connection.java +++ b/lib/src/main/java/io/ably/lib/realtime/Connection.java @@ -81,16 +81,6 @@ public String createRecoveryKey() { */ public String id; - /** - * The serial number of the last message to be received on this connection, - * used automatically by the library when recovering or resuming a connection. - * When recovering a connection explicitly, the recoveryKey is used in the recover - * client options as it contains both the key and the last message serial. - *

- * Spec: RTN10 - */ - public long serial; - /** * Explicitly calling connect() is unnecessary unless the autoConnect attribute of the {@link io.ably.lib.types.ClientOptions} * object is false. diff --git a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java index 7b18e7a9c..17d7b6489 100644 --- a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java +++ b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java @@ -1193,12 +1193,8 @@ public void onMessage(ITransport transport, ProtocolMessage message) throws Ably } private void onChannelMessage(ProtocolMessage message) { - if(message.connectionSerial != null) { - connection.serial = message.connectionSerial.longValue(); - if (connection.key != null) - connection.recoveryKey = connection.createRecoveryKey(); - } channels.onMessage(message); + connection.recoveryKey = connection.createRecoveryKey(); } private synchronized void onConnected(ProtocolMessage message) { @@ -1240,12 +1236,6 @@ private synchronized void onConnected(ProtocolMessage message) { connection.id = message.connectionId; - if(message.connectionSerial != null) { - connection.serial = message.connectionSerial; - if (connection.key != null) - connection.recoveryKey = connection.createRecoveryKey(); - } - ConnectionDetails connectionDetails = message.connectionDetails; /* Get any parameters from connectionDetails. */ connection.key = connectionDetails.connectionKey; //RTN16d @@ -1260,6 +1250,9 @@ private synchronized void onConnected(ProtocolMessage message) { requestState(transport, new StateIndication(ConnectionState.failed, e.errorInfo)); return; } + + connection.recoveryKey = connection.createRecoveryKey(); + /* indicated connected currentState */ final StateIndication stateIndication = new StateIndication(ConnectionState.connected, error, null, null, reattachOnResumeFailure); @@ -1504,7 +1497,6 @@ private class ConnectParams extends TransportParams { ConnectParams(ClientOptions options, PlatformAgentProvider platformAgentProvider) { super(options, platformAgentProvider); this.connectionKey = connection.key; - this.connectionSerial = String.valueOf(connection.serial); this.port = Defaults.getPort(options); } } diff --git a/lib/src/main/java/io/ably/lib/transport/ITransport.java b/lib/src/main/java/io/ably/lib/transport/ITransport.java index 9dadb54a5..ad424a64e 100644 --- a/lib/src/main/java/io/ably/lib/transport/ITransport.java +++ b/lib/src/main/java/io/ably/lib/transport/ITransport.java @@ -33,7 +33,6 @@ class TransportParams { protected String host; protected int port; protected String connectionKey; - protected String connectionSerial; protected Mode mode; protected boolean heartbeats; private final PlatformAgentProvider platformAgentProvider; @@ -65,8 +64,6 @@ public Param[] getConnectParams(Param[] baseParams) { if(connectionKey != null) { mode = Mode.resume; paramList.add(new Param("resume", connectionKey)); - if(connectionSerial != null) - paramList.add(new Param("connectionSerial", connectionSerial)); } else if(options.recover != null && !options.recover.isEmpty()) { // RTN16k mode = Mode.recover; RecoveryKeyContext recoveryKeyContext = RecoveryKeyContext.decode(options.recover); diff --git a/lib/src/main/java/io/ably/lib/types/ProtocolMessage.java b/lib/src/main/java/io/ably/lib/types/ProtocolMessage.java index 1a9d42629..1d1d3bc69 100644 --- a/lib/src/main/java/io/ably/lib/types/ProtocolMessage.java +++ b/lib/src/main/java/io/ably/lib/types/ProtocolMessage.java @@ -98,7 +98,6 @@ public ProtocolMessage(Action action, String channel) { public String channel; public String channelSerial; public String connectionId; - public Long connectionSerial; public Long msgSerial; public long timestamp; public Message[] messages; @@ -198,9 +197,6 @@ ProtocolMessage readMsgpack(MessageUnpacker unpacker) throws IOException { case "connectionId": connectionId = unpacker.unpackString(); break; - case "connectionSerial": - connectionSerial = Long.valueOf(unpacker.unpackLong()); - break; case "msgSerial": msgSerial = Long.valueOf(unpacker.unpackLong()); break; From 130305b540571be2e387db45bde1a8e8072c5b06 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Tue, 28 Nov 2023 22:58:52 +0530 Subject: [PATCH 14/22] Added explicit null checks for recoveryKey --- lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java | 3 ++- .../main/java/io/ably/lib/transport/ConnectionManager.java | 5 +++++ lib/src/main/java/io/ably/lib/transport/ITransport.java | 5 +++-- lib/src/main/java/io/ably/lib/util/StringUtils.java | 5 +++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java index 8e3a77035..8ac553c33 100644 --- a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java +++ b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java @@ -12,6 +12,7 @@ import io.ably.lib.types.*; import io.ably.lib.util.InternalMap; import io.ably.lib.util.Log; +import io.ably.lib.util.StringUtils; /** * A client that extends the functionality of the {@link AblyRest} and provides additional realtime-specific features. @@ -66,7 +67,7 @@ public void onConnectionStateChanged(ConnectionStateListener.ConnectionStateChan } }); - if (options.recover != null && !options.recover.isEmpty()) { + if (!StringUtils.isNullOrEmpty(options.recover)) { RecoveryKeyContext recoveryKeyContext = RecoveryKeyContext.decode(options.recover); if (recoveryKeyContext != null) { setChannelSerialsFromRecoverOption(recoveryKeyContext.getChannelSerials()); diff --git a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java index 17d7b6489..905e8728f 100644 --- a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java +++ b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java @@ -34,6 +34,7 @@ import io.ably.lib.util.Log; import io.ably.lib.util.PlatformAgentProvider; import io.ably.lib.util.ReconnectionStrategy; +import io.ably.lib.util.StringUtils; public class ConnectionManager implements ConnectListener { final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); @@ -1202,6 +1203,10 @@ private synchronized void onConnected(ProtocolMessage message) { boolean reattachOnResumeFailure = false; // this will indicate that channel must reattach when connected // event is received + boolean isConnectionResumeOrRecoverAttempt = !StringUtils.isNullOrEmpty(connection.key) || + !StringUtils.isNullOrEmpty(ably.options.recover); + ably.options.recover = null; // RTN16k, explicitly setting null, so it won't be used for subsequent connection requests + connection.reason = error; if (connection.id != null) { // there was a previous connection, so this is a resume and RTN15c applies Log.d(TAG, "There was a connection resume"); diff --git a/lib/src/main/java/io/ably/lib/transport/ITransport.java b/lib/src/main/java/io/ably/lib/transport/ITransport.java index ad424a64e..9f077bf95 100644 --- a/lib/src/main/java/io/ably/lib/transport/ITransport.java +++ b/lib/src/main/java/io/ably/lib/transport/ITransport.java @@ -4,6 +4,7 @@ import io.ably.lib.util.AgentHeaderCreator; import io.ably.lib.util.Log; import io.ably.lib.util.PlatformAgentProvider; +import io.ably.lib.util.StringUtils; import java.io.IOException; import java.util.ArrayList; @@ -61,10 +62,10 @@ public Param[] getConnectParams(Param[] baseParams) { paramList.add(new Param("format", (options.useBinaryProtocol ? "msgpack" : "json"))); if(!options.echoMessages) paramList.add(new Param("echo", "false")); - if(connectionKey != null) { + if(!StringUtils.isNullOrEmpty(connectionKey)) { mode = Mode.resume; paramList.add(new Param("resume", connectionKey)); - } else if(options.recover != null && !options.recover.isEmpty()) { // RTN16k + } else if(!StringUtils.isNullOrEmpty(options.recover)) { // RTN16k mode = Mode.recover; RecoveryKeyContext recoveryKeyContext = RecoveryKeyContext.decode(options.recover); if (recoveryKeyContext != null) { diff --git a/lib/src/main/java/io/ably/lib/util/StringUtils.java b/lib/src/main/java/io/ably/lib/util/StringUtils.java index 97f876b4a..d527fa105 100644 --- a/lib/src/main/java/io/ably/lib/util/StringUtils.java +++ b/lib/src/main/java/io/ably/lib/util/StringUtils.java @@ -4,6 +4,11 @@ import io.ably.lib.http.HttpCore; public class StringUtils { + + public static boolean isNullOrEmpty(String value) { + return value == null || value.isEmpty(); + } + public static Serialisation.FromJsonElement fromJsonElement = new Serialisation.FromJsonElement() { @Override public String fromJsonElement(JsonElement e) { From 3c0452381a0c18d9d8261eeb2e8e55b130da21ed Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Wed, 29 Nov 2023 17:55:30 +0530 Subject: [PATCH 15/22] Implemented channel serial for message reeived --- .../java/io/ably/lib/realtime/ChannelBase.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java index 5042d1c9a..732484d3e 100644 --- a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java +++ b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java @@ -37,6 +37,7 @@ import io.ably.lib.util.EventEmitter; import io.ably.lib.util.Log; import io.ably.lib.util.ReconnectionStrategy; +import io.ably.lib.util.StringUtils; /** * Enables messages to be published and subscribed to. @@ -248,8 +249,9 @@ private void attachImpl(final boolean forceReattach, final CompletionListener li } } if(this.decodeFailureRecoveryInProgress) { - attachMessage.channelSerial = this.lastPayloadProtocolMessageChannelSerial; + Log.v(TAG, "attach(); message decode recovery in progress."); } + attachMessage.channelSerial = properties.channelSerial; try { if (listener != null) { on(new ChannelStateCompletionListener(listener, ChannelState.attached, ChannelState.failed)); @@ -850,7 +852,6 @@ private void onMessage(final ProtocolMessage protocolMessage) { } lastPayloadMessageId = lastMessage.id; - lastPayloadProtocolMessageChannelSerial = protocolMessage.channelSerial; for (final Message msg : messages) { this.listeners.onMessage(msg); @@ -1264,6 +1265,15 @@ else if(stateChange.current.equals(failureState)) { } void onChannelMessage(ProtocolMessage msg) { + // RTL15b + if (!StringUtils.isNullOrEmpty(msg.channelSerial) && (msg.action == Action.message || + msg.action == Action.presence || msg.action == Action.attached)) { + Log.v(TAG, String.format( + Locale.ROOT, "Setting channel serial for channelName - %s, previous - %s, current - %s", + name, properties.channelSerial, msg.channelSerial)); + properties.channelSerial = msg.channelSerial; + } + switch(msg.action) { case attached: setAttached(msg); @@ -1369,7 +1379,6 @@ public void once(ChannelState state, ChannelStateListener listener) { */ private Set modes; private String lastPayloadMessageId; - private String lastPayloadProtocolMessageChannelSerial; private boolean decodeFailureRecoveryInProgress; private final DecodingContext decodingContext; } From 0efffdfe151d00c0592e64b730d0c3ff074b7a63 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Wed, 29 Nov 2023 18:14:44 +0530 Subject: [PATCH 16/22] Added missing implementation for channel detach when attached msg received --- .../main/java/io/ably/lib/realtime/ChannelBase.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java index 732484d3e..effa5dfee 100644 --- a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java +++ b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java @@ -401,7 +401,15 @@ private void setAttached(ProtocolMessage message) { Log.v(TAG, String.format(Locale.ROOT, "Server initiated attach for channel %s", name)); /* emit UPDATE event according to RTL12 */ emitUpdate(null, resumed); - } else { + } else if (state == ChannelState.detaching || state == ChannelState.detached) { //RTL5k + Log.v(TAG, "setAttached(): channel is in detaching state so no need to attach it!"); + try { + detach(); + } catch (AblyException e) { + Log.e(TAG, e.getMessage(), e); + } + } + else { this.attachResume = true; setState(ChannelState.attached, message.error, resumed); presence.setAttached(message.hasFlag(Flag.has_presence), this.ably.connection.id); From 3ebeed700346cb7d6292f1246e07b9ff87d9815d Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Wed, 29 Nov 2023 18:29:37 +0530 Subject: [PATCH 17/22] Updated code to send explicit detach message when attached received in detach state --- .../main/java/io/ably/lib/realtime/ChannelBase.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java index effa5dfee..7d0816377 100644 --- a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java +++ b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java @@ -327,7 +327,10 @@ private void detachImpl(CompletionListener listener) throws AblyException { if(!connectionManager.isActive()) throw AblyException.fromErrorInfo(connectionManager.getStateErrorInfo()); - /* send detach request */ + sendDetachMessage(listener); + } + + private void sendDetachMessage(CompletionListener listener) throws AblyException { ProtocolMessage detachMessage = new ProtocolMessage(Action.detach, this.name); try { if (listener != null) { @@ -340,7 +343,7 @@ private void detachImpl(CompletionListener listener) throws AblyException { } else { setState(ChannelState.detaching, null); } - connectionManager.send(detachMessage, true, null); + ably.connection.connectionManager.send(detachMessage, true, null); } catch(AblyException e) { throw e; } @@ -402,9 +405,9 @@ private void setAttached(ProtocolMessage message) { /* emit UPDATE event according to RTL12 */ emitUpdate(null, resumed); } else if (state == ChannelState.detaching || state == ChannelState.detached) { //RTL5k - Log.v(TAG, "setAttached(): channel is in detaching state so no need to attach it!"); + Log.v(TAG, "setAttached(): channel is in detaching state, as per RTL5k sending detach message!"); try { - detach(); + sendDetachMessage(null); } catch (AblyException e) { Log.e(TAG, e.getMessage(), e); } From d4654891eccec9660ad13b7a767fe0db1a7c8e27 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Thu, 30 Nov 2023 17:56:23 +0530 Subject: [PATCH 18/22] Clearing channel serial as per RTP5a1 --- lib/src/main/java/io/ably/lib/realtime/ChannelBase.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java index 7d0816377..d38a74df1 100644 --- a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java +++ b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java @@ -132,6 +132,11 @@ private void setState(ChannelState newState, ErrorInfo reason, boolean resumed, this.retryCount = 0; } + // RTP5a1 + if (newState == ChannelState.detached || newState == ChannelState.suspended || newState == ChannelState.failed) { + properties.channelSerial = null; + } + if(notifyStateChange) { /* broadcast state change */ emit(newState, stateChange); From b42ff87ad98c55eeefb13d6f372e843fd5511cf2 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Fri, 1 Dec 2023 16:39:47 +0530 Subject: [PATCH 19/22] resetting message serial on failed connection resume or recover --- .../main/java/io/ably/lib/transport/ConnectionManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java index 905e8728f..34d006932 100644 --- a/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java +++ b/lib/src/main/java/io/ably/lib/transport/ConnectionManager.java @@ -1205,6 +1205,10 @@ private synchronized void onConnected(ProtocolMessage message) { boolean isConnectionResumeOrRecoverAttempt = !StringUtils.isNullOrEmpty(connection.key) || !StringUtils.isNullOrEmpty(ably.options.recover); + boolean failedResumeOrRecover = !message.connectionId.equals(connection.id) && message.error != null; // RTN15c7, RTN16d + if (isConnectionResumeOrRecoverAttempt && failedResumeOrRecover) { // RTN15c7 + msgSerial = 0; + } ably.options.recover = null; // RTN16k, explicitly setting null, so it won't be used for subsequent connection requests connection.reason = error; From 5b8ab5efa9e3da8b85d048ed05b59a7f62d7fae4 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Fri, 1 Dec 2023 16:44:39 +0530 Subject: [PATCH 20/22] Fixed AblyRealtime as class imports --- lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java index 8ac553c33..c9b9a9d4d 100644 --- a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java +++ b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java @@ -9,7 +9,13 @@ import io.ably.lib.rest.AblyRest; import io.ably.lib.rest.Auth; import io.ably.lib.transport.ConnectionManager; -import io.ably.lib.types.*; +import io.ably.lib.types.AblyException; +import io.ably.lib.types.ChannelOptions; +import io.ably.lib.types.ClientOptions; +import io.ably.lib.types.ErrorInfo; +import io.ably.lib.types.ProtocolMessage; +import io.ably.lib.types.ReadOnlyMap; +import io.ably.lib.types.RecoveryKeyContext; import io.ably.lib.util.InternalMap; import io.ably.lib.util.Log; import io.ably.lib.util.StringUtils; From bb42aea29baf964de55957e6fb3f3221e73f681f Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Fri, 1 Dec 2023 17:43:03 +0530 Subject: [PATCH 21/22] refactored ably protocol and agent headers in accordance with version id --- .../main/java/io/ably/lib/http/HttpCore.java | 2 +- .../java/io/ably/lib/transport/Defaults.java | 20 +++++++------------ .../io/ably/lib/transport/ITransport.java | 2 +- .../io/ably/lib/types/ChannelProperties.java | 3 +++ .../java/io/ably/lib/types/ClientOptions.java | 2 +- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/http/HttpCore.java b/lib/src/main/java/io/ably/lib/http/HttpCore.java index 8277fe3d9..dc1255bc9 100644 --- a/lib/src/main/java/io/ably/lib/http/HttpCore.java +++ b/lib/src/main/java/io/ably/lib/http/HttpCore.java @@ -209,7 +209,7 @@ T httpExecute(HttpURLConnection conn, String method, Param[] headers, Reques if(!acceptSet) { conn.setRequestProperty(HttpConstants.Headers.ACCEPT, HttpConstants.ContentTypes.JSON); } /* pass required headers */ - conn.setRequestProperty(Defaults.ABLY_VERSION_HEADER, Defaults.ABLY_VERSION); + conn.setRequestProperty(Defaults.ABLY_PROTOCOL_VERSION_HEADER, Defaults.ABLY_PROTOCOL_VERSION); conn.setRequestProperty(Defaults.ABLY_AGENT_HEADER, AgentHeaderCreator.create(options.agents, platformAgentProvider)); /* prepare request body */ diff --git a/lib/src/main/java/io/ably/lib/transport/Defaults.java b/lib/src/main/java/io/ably/lib/transport/Defaults.java index 9d274e572..ba06838da 100644 --- a/lib/src/main/java/io/ably/lib/transport/Defaults.java +++ b/lib/src/main/java/io/ably/lib/transport/Defaults.java @@ -3,28 +3,22 @@ import io.ably.lib.BuildConfig; import io.ably.lib.types.ClientOptions; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.Locale; - public class Defaults { - public static final float ABLY_VERSION_NUMBER = 1.0f; - /** * The level of compatibility with the Ably service that this SDK supports, also referred to as the 'wire protocol version'. * This value is presented as a string, as specified in G4a. */ - public static final String ABLY_VERSION = new DecimalFormat("0.0", new DecimalFormatSymbols(Locale.ENGLISH)).format(ABLY_VERSION_NUMBER); + public static final String ABLY_PROTOCOL_VERSION = "2"; public static final String ABLY_AGENT_VERSION = String.format("%s/%s", "ably-java", BuildConfig.VERSION); - /* params */ - public static final String ABLY_VERSION_PARAM = "v"; - public static final String ABLY_AGENT_PARAM = "agent"; + /* realtime params */ + public static final String ABLY_PROTOCOL_VERSION_PARAM = "v"; + public static final String ABLY_AGENT_PARAM = "agent"; - /* Headers */ - public static final String ABLY_VERSION_HEADER = "X-Ably-Version"; - public static final String ABLY_AGENT_HEADER = "Ably-Agent"; + /* http headers */ + public static final String ABLY_PROTOCOL_VERSION_HEADER = "X-Ably-Version"; + public static final String ABLY_AGENT_HEADER = "Ably-Agent"; /* Hosts */ public static final String[] HOST_FALLBACKS = { "A.ably-realtime.com", "B.ably-realtime.com", "C.ably-realtime.com", "D.ably-realtime.com", "E.ably-realtime.com" }; diff --git a/lib/src/main/java/io/ably/lib/transport/ITransport.java b/lib/src/main/java/io/ably/lib/transport/ITransport.java index 9f077bf95..6e188f3d9 100644 --- a/lib/src/main/java/io/ably/lib/transport/ITransport.java +++ b/lib/src/main/java/io/ably/lib/transport/ITransport.java @@ -58,7 +58,7 @@ public ClientOptions getClientOptions() { public Param[] getConnectParams(Param[] baseParams) { List paramList = new ArrayList(Arrays.asList(baseParams)); - paramList.add(new Param(Defaults.ABLY_VERSION_PARAM, Defaults.ABLY_VERSION)); + paramList.add(new Param(Defaults.ABLY_PROTOCOL_VERSION_PARAM, Defaults.ABLY_PROTOCOL_VERSION)); paramList.add(new Param("format", (options.useBinaryProtocol ? "msgpack" : "json"))); if(!options.echoMessages) paramList.add(new Param("echo", "false")); diff --git a/lib/src/main/java/io/ably/lib/types/ChannelProperties.java b/lib/src/main/java/io/ably/lib/types/ChannelProperties.java index 50a1ae989..482528d18 100644 --- a/lib/src/main/java/io/ably/lib/types/ChannelProperties.java +++ b/lib/src/main/java/io/ably/lib/types/ChannelProperties.java @@ -2,6 +2,9 @@ /** * Describes the properties of the channel state. + *

+ * Spec: CP2 + *

*/ public class ChannelProperties { /** diff --git a/lib/src/main/java/io/ably/lib/types/ClientOptions.java b/lib/src/main/java/io/ably/lib/types/ClientOptions.java index 06a2fae02..7a480b5f5 100644 --- a/lib/src/main/java/io/ably/lib/types/ClientOptions.java +++ b/lib/src/main/java/io/ably/lib/types/ClientOptions.java @@ -147,7 +147,7 @@ public ClientOptions(String key) throws AblyException { * when the connection is recoverable. The callback is then responsible for confirming whether the connection * should be recovered or not. See connection state recovery for further information. *

- * Spec: RTC1c, TO3i + * Spec: RTC1c, TO3i, RTN16i */ public String recover; From 5b8e5b7422b3255e813852441964c2f177d85270 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Fri, 1 Dec 2023 17:43:16 +0530 Subject: [PATCH 22/22] Updated test for protocol version --- lib/src/test/java/io/ably/lib/transport/DefaultsTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/test/java/io/ably/lib/transport/DefaultsTest.java b/lib/src/test/java/io/ably/lib/transport/DefaultsTest.java index 021387da4..cdeec5dce 100644 --- a/lib/src/test/java/io/ably/lib/transport/DefaultsTest.java +++ b/lib/src/test/java/io/ably/lib/transport/DefaultsTest.java @@ -8,8 +8,8 @@ public class DefaultsTest { @Test - public void versions() { - assertThat(Defaults.ABLY_VERSION, is("1.0")); + public void protocol_version_CSV2() { + assertThat(Defaults.ABLY_PROTOCOL_VERSION, is("2")); } @Test