Skip to content

Commit 22e52c8

Browse files
authored
Merge pull request #1335 from couchbase/feature/issue_1315
Fixed #1315 - Replicator shouldn't go to IDLE state if the authentica…
2 parents 8ddd666 + 09c7391 commit 22e52c8

2 files changed

Lines changed: 64 additions & 15 deletions

File tree

src/main/java/com/couchbase/lite/replicator/ReplicationInternal.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.couchbase.lite.auth.Authenticator;
2525
import com.couchbase.lite.auth.Authorizer;
2626
import com.couchbase.lite.auth.LoginAuthorizer;
27+
import com.couchbase.lite.auth.OpenIDConnectAuthorizer;
2728
import com.couchbase.lite.auth.SessionCookieAuthorizer;
2829
import com.couchbase.lite.internal.InterfaceAudience;
2930
import com.couchbase.lite.internal.RevisionInternal;
@@ -84,6 +85,13 @@ abstract class ReplicationInternal implements BlockingQueueListener {
8485
private static int lastSessionID = 0;
8586
public static int RETRY_DELAY_SECONDS = 60; // #define kRetryDelay 60.0 in CBL_Replicator.m
8687

88+
private static ReplicationStateTransition TRANS_RUNNING_TO_IDLE =
89+
new ReplicationStateTransition(ReplicationState.RUNNING,
90+
ReplicationState.IDLE, ReplicationTrigger.WAITING_FOR_CHANGES);
91+
private static ReplicationStateTransition TRANS_IDLE_TO_RUNNING =
92+
new ReplicationStateTransition(ReplicationState.IDLE,
93+
ReplicationState.RUNNING, ReplicationTrigger.RESUME);
94+
8795
// Change listeners can be called back synchronously or asynchronously.
8896
protected enum ChangeListenerNotifyStyle {
8997
SYNC, ASYNC
@@ -95,6 +103,7 @@ protected enum ChangeListenerNotifyStyle {
95103
protected HttpClientFactory clientFactory;
96104
protected String lastSequence;
97105
protected Authenticator authenticator;
106+
protected boolean authenticating = false;
98107
protected String filterName;
99108
protected Map<String, Object> filterParams;
100109
protected List<String> documentIDs;
@@ -148,6 +157,7 @@ protected enum ChangeListenerNotifyStyle {
148157
this.clientFactory = clientFactory;
149158
this.lifecycle = lifecycle;
150159
this.requestHeaders = new HashMap<String, Object>();
160+
this.authenticating = false;
151161

152162
// The reason that notifications are ASYNC is to make the public API call
153163
// Replication.getStatus() work as expected. Because if this is set to SYNC,
@@ -252,6 +262,7 @@ protected void start() {
252262
}
253263
db.addReplication(parentReplication);
254264
db.addActiveReplication(parentReplication);
265+
this.authenticating = false;
255266
initSessionId();
256267
// initialize batcher
257268
initBatcher();
@@ -298,6 +309,8 @@ protected void goOnline() {
298309
* Close all resources associated with this replicator.
299310
*/
300311
protected void close() {
312+
this.authenticating = false;
313+
301314
// cancel pending futures
302315
for (Future future : pendingFutures) {
303316
future.cancel(false);
@@ -426,6 +439,7 @@ protected void checkSession() {
426439

427440
@InterfaceAudience.Private
428441
protected void checkSessionAtPath(final String sessionPath) {
442+
// First check whether a session exists
429443
Future future = sendAsyncRequest("GET", sessionPath, null, new RemoteRequestCompletion() {
430444

431445
@Override
@@ -470,6 +484,8 @@ public void onCompletion(Response _response, Object result, Throwable err) {
470484

471485
@InterfaceAudience.Private
472486
protected void login() {
487+
authenticating = true;
488+
473489
final LoginAuthorizer loginAuth;
474490
List<Object> login = null;
475491
loginAuth = getAuthenticator() instanceof LoginAuthorizer ? (LoginAuthorizer) getAuthenticator() : null;
@@ -520,6 +536,8 @@ public void run(Database database) {
520536
}
521537

522538
private void loginFinishedWithError(Throwable error) {
539+
authenticating = false;
540+
523541
if (error != null) {
524542
Log.v(TAG, "%s: Login error: %s", this, error.getMessage());
525543
setError(error);
@@ -1183,6 +1201,7 @@ public boolean canSendCompressedRequests() {
11831201
* Actual work of stopping the replication process.
11841202
*/
11851203
protected void stop() {
1204+
this.authenticating = false;
11861205
// clear batcher
11871206
batcher.clear();
11881207
// set non-continuous
@@ -1452,9 +1471,19 @@ private void logTransition(Transition<ReplicationState, ReplicationTrigger> tran
14521471
transition.getSource(), transition.getDestination(), transition.getTrigger(), this);
14531472
}
14541473

1455-
private void notifyChangeListenersStateTransition(Transition<ReplicationState, ReplicationTrigger> transition) {
1474+
private void notifyChangeListenersStateTransition(
1475+
Transition<ReplicationState, ReplicationTrigger> transition) {
14561476
logTransition(transition);
1457-
Replication.ChangeEvent changeEvent = new Replication.ChangeEvent(this, new ReplicationStateTransition(transition));
1477+
1478+
ReplicationStateTransition replStateTrans = new ReplicationStateTransition(transition);
1479+
1480+
if ((TRANS_RUNNING_TO_IDLE.equals(replStateTrans)
1481+
|| TRANS_IDLE_TO_RUNNING.equals(replStateTrans)) && authenticating) {
1482+
Log.i(TAG, "During middle of authentication, not notify Replicator state change");
1483+
return;
1484+
}
1485+
1486+
Replication.ChangeEvent changeEvent = new Replication.ChangeEvent(this, replStateTrans);
14581487
notifyChangeListeners(changeEvent);
14591488
}
14601489

src/main/java/com/couchbase/lite/replicator/ReplicationStateTransition.java

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
/**
2-
* Copyright (c) 2016 Couchbase, Inc. All rights reserved.
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5-
* except in compliance with the License. You may obtain a copy of the License at
6-
*
7-
* http://www.apache.org/licenses/LICENSE-2.0
8-
*
9-
* Unless required by applicable law or agreed to in writing, software distributed under the
10-
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11-
* either express or implied. See the License for the specific language governing permissions
12-
* and limitations under the License.
13-
*/
1+
//
2+
// Copyright (c) 2016 Couchbase, Inc. All rights reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5+
// except in compliance with the License. You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software distributed under the
10+
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11+
// either express or implied. See the License for the specific language governing permissions
12+
// and limitations under the License.
13+
//
1414
package com.couchbase.lite.replicator;
1515

1616
import com.github.oxo42.stateless4j.transitions.Transition;
@@ -61,4 +61,24 @@ public ReplicationTrigger getTrigger() {
6161
this.trigger = trigger;
6262
}
6363

64+
@Override
65+
public boolean equals(Object o) {
66+
if (this == o) return true;
67+
if (o == null || getClass() != o.getClass()) return false;
68+
69+
ReplicationStateTransition that = (ReplicationStateTransition) o;
70+
71+
if (source != that.source) return false;
72+
if (destination != that.destination) return false;
73+
return trigger == that.trigger;
74+
75+
}
76+
77+
@Override
78+
public int hashCode() {
79+
int result = source.hashCode();
80+
result = 31 * result + destination.hashCode();
81+
result = 31 * result + trigger.hashCode();
82+
return result;
83+
}
6484
}

0 commit comments

Comments
 (0)