com.microsoft.azure.documentdb.internal.RenameCollectionAwareClientRetryPolicy Maven / Gradle / Ivy
package com.microsoft.azure.documentdb.internal;
import java.net.URI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.microsoft.azure.documentdb.ConnectionMode;
import com.microsoft.azure.documentdb.DocumentClientException;
import com.microsoft.azure.documentdb.DocumentCollection;
import com.microsoft.azure.documentdb.internal.HttpConstants.HttpHeaders;
import com.microsoft.azure.documentdb.internal.routing.ClientCollectionCache;
public class RenameCollectionAwareClientRetryPolicy implements RetryPolicy {
private ClientCollectionCache clientCollectionCache;
private DocumentServiceRequest currentRequest;
private ConnectionMode connectionMode;
private EndpointManager globalEndpointManager;
private static final int retryIntervalInMS = 0;
private boolean isTriggered;
private static final Logger LOGGER = LoggerFactory.getLogger(RenameCollectionAwareClientRetryPolicy.class);
public RenameCollectionAwareClientRetryPolicy(ClientCollectionCache clientCollectionCache, ConnectionMode connectionMode, EndpointManager globalEndpointManager, DocumentServiceRequest currentRequest) {
this.clientCollectionCache = clientCollectionCache;
this.currentRequest = currentRequest;
this.connectionMode = connectionMode;
this.globalEndpointManager = globalEndpointManager;
}
@Override
public boolean shouldRetry(DocumentClientException exception) throws DocumentClientException {
if (currentRequest.shouldClearSessionTokenOnSessionReadFailure() && !isTriggered) {
if (currentRequest.getIsNameBased()) {
isTriggered = true;
// Set locationEndpoint for the request as it will be removed in the after last retry
// using sessionReadRetryPolicy
URI locationEndpoint = this.globalEndpointManager.resolveServiceEndpoint(currentRequest);
currentRequest.routeToLocation(locationEndpoint);
if (connectionMode == ConnectionMode.DirectHttps) {
resetSessionTokenOnRequest();
return true;
}
String oldCollectionRid = currentRequest.getResolvedCollectionRid();
currentRequest.setForceNameCacheRefresh(true);
currentRequest.setResolvedCollectionRid(null);
try {
DocumentCollection collectionInfo = this.clientCollectionCache.resolveCollection(currentRequest);
if (collectionInfo == null) {
LOGGER.debug(String.format("Can't recover from session unavailable exception because resolving collection name %s returned null", currentRequest.getResourceAddress()));
} else if (!Strings.isNullOrEmpty(oldCollectionRid) && !Strings.isNullOrEmpty(collectionInfo.getResourceId())) {
resetSessionTokenOnRequest();
return true;
}
} catch (Exception e) {
// When ResolveCollectionAsync throws an exception ignore it because it's an attempt to recover an existing
// error. When the recovery fails we return false and propaganate the original exception to the client
LOGGER.debug(String.format("Can't recover from session unavailable exception because resolving collection name %s failed with %s", currentRequest.getResourceAddress(), e.getMessage()));
throw e;
}
}
}
return false;
}
private void resetSessionTokenOnRequest() {
currentRequest.setSessionToken(null);
currentRequest.getHeaders().remove(HttpHeaders.SESSION_TOKEN);
currentRequest.setShouldClearSessionTokenOnSessionReadFailure(false);
}
@Override
public long getRetryAfterInMilliseconds() {
return retryIntervalInMS;
}
}