Skip to content

Commit dc30b41

Browse files
authored
Merge pull request #1043 from ably/fix/RTP6e-implicit-channel-attach
[ECO-4972] Fix implicit channel ATTACH
2 parents 6a66eec + 43f2eaa commit dc30b41

File tree

5 files changed

+52
-19
lines changed

5 files changed

+52
-19
lines changed

lib/src/main/java/io/ably/lib/realtime/ChannelBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ public synchronized void unsubscribe() {
695695
* Checks if {@link io.ably.lib.types.ChannelOptions#attachOnSubscribe} is true.
696696
* </p>
697697
* Defaults to {@code true} when {@link io.ably.lib.realtime.ChannelBase#options} is null.
698-
* <p>Spec: TB4, RTL7g, RTL7gh, RTP6d, RTP6e</p>
698+
* <p>Spec: TB4, RTL7g, RTL7h, RTP6d, RTP6e</p>
699699
*/
700700
protected boolean attachOnSubscribeEnabled() {
701701
return options == null || options.attachOnSubscribe;

lib/src/main/java/io/ably/lib/realtime/Presence.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -296,27 +296,26 @@ public void unsubscribe() {
296296
eventListeners.clear();
297297
}
298298

299-
300-
/***
301-
* internal
302-
*
303-
*/
304-
305299
/**
306-
* Implicitly attach channel on subscribe. Throw exception if channel is in failed state
307-
* @param completionListener
308-
* @throws AblyException
300+
* Implicitly attach channel on subscribe. Throw exception if channel is in failed state.
301+
* @param completionListener Registers listener, gets called when ATTACH operation is a success.
302+
* @throws AblyException Throws exception when channel is in failed state.
309303
*/
310304
private void implicitAttachOnSubscribe(CompletionListener completionListener) throws AblyException {
305+
// RTP6e
311306
if (!channel.attachOnSubscribeEnabled()) {
312307
if (completionListener != null) {
313-
completionListener.onSuccess();
308+
String errorString = String.format(
309+
"Channel %s: attachOnSubscribe=false doesn't expect attach completion callback", channel.name);
310+
Log.e(TAG, errorString);
311+
ErrorInfo errorInfo = new ErrorInfo(errorString, 400,40000);
312+
throw AblyException.fromErrorInfo(errorInfo);
314313
}
315314
return;
316315
}
317316
if (channel.state == ChannelState.failed) {
318317
String errorString = String.format(Locale.ROOT, "Channel %s: subscribe in FAILED channel state", channel.name);
319-
Log.v(TAG, errorString);
318+
Log.e(TAG, errorString);
320319
ErrorInfo errorInfo = new ErrorInfo(errorString, 90001);
321320
throw AblyException.fromErrorInfo(errorInfo);
322321
}

lib/src/main/java/io/ably/lib/types/ChannelOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class ChannelOptions {
4747
* should trigger an implicit attach.
4848
* </p>
4949
* <p>Defaults to {@code true}.</p>
50-
* <p>Spec: TB4, RTL7g, RTL7gh, RTP6d, RTP6e</p>
50+
* <p>Spec: TB4, RTL7g, RTL7h, RTP6d, RTP6e</p>
5151
*/
5252
public boolean attachOnSubscribe = true;
5353

lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ public void onMessage(Message message) {
396396
/**
397397
* <p>
398398
* Validates a client can subscribe to messages without implicit channel attach
399-
* Refer Spec TB4, RTL7g, RTL7gh
399+
* Refer Spec TB4, RTL7g, RTL7h
400400
* </p>
401401
* @throws AblyException
402402
*/

lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.ably.lib.test.realtime;
22

3+
import static org.hamcrest.CoreMatchers.containsString;
34
import static org.hamcrest.Matchers.empty;
45
import static org.hamcrest.Matchers.emptyCollectionOf;
56
import static org.hamcrest.Matchers.equalTo;
@@ -1647,15 +1648,12 @@ public void presence_subscribe_without_implicit_attach() {
16471648
channel.setOptions(chOpts);
16481649

16491650
List<Boolean> receivedPresenceMsg = Collections.synchronizedList(new ArrayList<>());
1650-
CompletionWaiter completionWaiter = new CompletionWaiter();
16511651

16521652
/* Check for all subscriptions without ATTACHING state */
1653-
channel.presence.subscribe(m -> receivedPresenceMsg.add(true), completionWaiter);
1654-
assertEquals(1, completionWaiter.successCount);
1653+
channel.presence.subscribe(m -> receivedPresenceMsg.add(true));
16551654
assertEquals(ChannelState.initialized, channel.state);
16561655

1657-
channel.presence.subscribe(Action.enter, m -> receivedPresenceMsg.add(true), completionWaiter);
1658-
assertEquals(2, completionWaiter.successCount);
1656+
channel.presence.subscribe(Action.enter, m -> receivedPresenceMsg.add(true));
16591657
assertEquals(ChannelState.initialized, channel.state);
16601658

16611659
channel.presence.subscribe(EnumSet.of(Action.enter, Action.leave),m -> receivedPresenceMsg.add(true));
@@ -1686,6 +1684,42 @@ public void presence_subscribe_without_implicit_attach() {
16861684
}
16871685
}
16881686

1687+
/**
1688+
* <p>
1689+
* Validates a client can subscribe to presence without implicit channel attach
1690+
* Refer Spec TB4, RTP6d, RTP6e
1691+
* </p>
1692+
* @throws AblyException
1693+
*/
1694+
@Test
1695+
public void presence_subscribe_without_implicit_attach_and_completion_listener_throws_exception() throws AblyException {
1696+
String ablyChannel = "subscribe_" + testParams.name;
1697+
ClientOptions option1 = createOptions(testVars.keys[0].keyStr);
1698+
option1.clientId = "client1";
1699+
try (AblyRealtime ably = new AblyRealtime(option1)) {
1700+
/* create a channel and set attachOnSubscribe to false */
1701+
final Channel channel = ably.channels.get(ablyChannel);
1702+
ChannelOptions chOpts = new ChannelOptions();
1703+
chOpts.attachOnSubscribe = false;
1704+
channel.setOptions(chOpts);
1705+
1706+
// When completionWaiter passed with attachOnSubscribe=false, throws exception.
1707+
CompletionWaiter completionWaiter = new CompletionWaiter();
1708+
try {
1709+
channel.presence.subscribe(m -> {}, completionWaiter);
1710+
} catch (AblyException e) {
1711+
assertEquals(400, e.errorInfo.statusCode);
1712+
assertEquals(40000, e.errorInfo.code);
1713+
assertThat(e.errorInfo.message, containsString("attachOnSubscribe=false doesn't expect attach completion callback"));
1714+
}
1715+
assertEquals(ChannelState.initialized, channel.state);
1716+
1717+
} catch (AblyException e) {
1718+
e.printStackTrace();
1719+
fail("presence_subscribe_without_implicit_attach: Unexpected exception");
1720+
}
1721+
}
1722+
16891723
/**
16901724
* <p>
16911725
* Validates a client sending multiple presence updates when the channel is in the attaching

0 commit comments

Comments
 (0)