Bug 963424 - Use token server-provided cluster URL. r=nalexander

This commit is contained in:
Richard Newman 2014-01-28 16:20:50 -08:00
parent 6adb819a5a
commit 51af941cf3
9 changed files with 137 additions and 76 deletions

View File

@ -801,6 +801,7 @@ sync_java_files = [
'sync/stage/ServerSyncStage.java',
'sync/stage/SyncClientsEngineStage.java',
'sync/stage/UploadMetaGlobalStage.java',
'sync/Sync11Configuration.java',
'sync/syncadapter/SyncAdapter.java',
'sync/syncadapter/SyncService.java',
'sync/SyncConfiguration.java',

View File

@ -33,9 +33,9 @@ public class FxAccountGlobalSession extends GlobalSession {
throws SyncConfigurationException, IllegalArgumentException, IOException,
ParseException, NonObjectJSONException, URISyntaxException {
super(config, callback, context, extras, clientsDelegate, null);
URI uri = new URI(storageEndpoint);
this.config.clusterURL = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), "/", null, null);
FxAccountConstants.pii(LOG_TAG, "storageEndpoint is " + uri + " and clusterURL is " + config.clusterURL);
URI storageURI = new URI(storageEndpoint);
this.config.setClusterURL(storageURI);
FxAccountConstants.pii(LOG_TAG, "clusterURL is " + config.getClusterURLString());
}
@Override

View File

@ -63,7 +63,6 @@ import ch.boye.httpclientandroidlib.HttpResponse;
public class GlobalSession implements PrefsSource, HttpResponseObserver {
private static final String LOG_TAG = "GlobalSession";
public static final String API_VERSION = "1.1";
public static final long STORAGE_VERSION = 5;
public SyncConfiguration config = null;

View File

@ -0,0 +1,84 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.sync;
import java.net.URI;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.crypto.KeyBundle;
import org.mozilla.gecko.sync.net.AuthHeaderProvider;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
/**
* Override SyncConfiguration to restore the old behavior of clusterURL --
* that is, a URL without the protocol version etc.
*
*/
public class Sync11Configuration extends SyncConfiguration {
private static final String LOG_TAG = "Sync11Configuration";
private static final String API_VERSION = "1.1";
public Sync11Configuration(String username,
AuthHeaderProvider authHeaderProvider,
SharedPreferences prefs) {
super(username, authHeaderProvider, prefs);
}
public Sync11Configuration(String username,
AuthHeaderProvider authHeaderProvider,
SharedPreferences prefs,
KeyBundle keyBundle) {
super(username, authHeaderProvider, prefs, keyBundle);
}
@Override
public String getAPIVersion() {
return API_VERSION;
}
@Override
public String storageURL() {
return clusterURL + API_VERSION + "/" + username + "/storage";
}
@Override
protected String infoBaseURL() {
return clusterURL + API_VERSION + "/" + username + "/info/";
}
protected void setAndPersistClusterURL(URI u, SharedPreferences prefs) {
boolean shouldPersist = (prefs != null) && (clusterURL == null);
Logger.trace(LOG_TAG, "Setting cluster URL to " + u.toASCIIString() +
(shouldPersist ? ". Persisting." : ". Not persisting."));
clusterURL = u;
if (shouldPersist) {
Editor edit = prefs.edit();
edit.putString(PREF_CLUSTER_URL, clusterURL.toASCIIString());
edit.commit();
}
}
protected void setClusterURL(URI u, SharedPreferences prefs) {
if (u == null) {
Logger.warn(LOG_TAG, "Refusing to set cluster URL to null.");
return;
}
URI uri = u.normalize();
if (uri.toASCIIString().endsWith("/")) {
setAndPersistClusterURL(u, prefs);
return;
}
setAndPersistClusterURL(uri.resolve("/"), prefs);
Logger.trace(LOG_TAG, "Set cluster URL to " + clusterURL.toASCIIString() + ", given input " + u.toASCIIString());
}
@Override
public void setClusterURL(URI u) {
setClusterURL(u, this.getPrefs());
}
}

View File

@ -258,6 +258,8 @@ public class SyncConfiguration {
public static final String PREF_CLIENT_NAME = "account.clientName";
public static final String PREF_NUM_CLIENTS = "account.numClients";
private static final String API_VERSION = "1.5";
/**
* Create a new SyncConfiguration instance. Pass in a PrefsSource to
* provide access to preferences.
@ -278,6 +280,10 @@ public class SyncConfiguration {
this.syncKeyBundle = syncKeyBundle;
}
public String getAPIVersion() {
return API_VERSION;
}
public SharedPreferences getPrefs() {
return this.prefs;
}
@ -453,8 +459,17 @@ public class SyncConfiguration {
collectionKeys = k;
}
/**
* Return path to storage endpoint without trailing slash.
*
* @return storage endpoint without trailing slash.
*/
public String storageURL() {
return clusterURL + "/storage";
}
protected String infoBaseURL() {
return clusterURL + GlobalSession.API_VERSION + "/" + username + "/info/";
return clusterURL + "/info/";
}
public String infoCollectionsURL() {
@ -469,15 +484,6 @@ public class SyncConfiguration {
return storageURL() + "/meta/global";
}
/**
* Return path to storage endpoint without trailing slash.
*
* @return storage endpoint without trailing slash.
*/
public String storageURL() {
return clusterURL + GlobalSession.API_VERSION + "/" + username + "/storage";
}
public URI collectionURI(String collection) throws URISyntaxException {
return new URI(storageURL() + "/" + collection);
}
@ -517,35 +523,8 @@ public class SyncConfiguration {
return clusterURL.toASCIIString();
}
protected void setAndPersistClusterURL(URI u, SharedPreferences prefs) {
boolean shouldPersist = (prefs != null) && (clusterURL == null);
Logger.trace(LOG_TAG, "Setting cluster URL to " + u.toASCIIString() +
(shouldPersist ? ". Persisting." : ". Not persisting."));
clusterURL = u;
if (shouldPersist) {
Editor edit = prefs.edit();
edit.putString(PREF_CLUSTER_URL, clusterURL.toASCIIString());
edit.commit();
}
}
protected void setClusterURL(URI u, SharedPreferences prefs) {
if (u == null) {
Logger.warn(LOG_TAG, "Refusing to set cluster URL to null.");
return;
}
URI uri = u.normalize();
if (uri.toASCIIString().endsWith("/")) {
setAndPersistClusterURL(u, prefs);
return;
}
setAndPersistClusterURL(uri.resolve("/"), prefs);
Logger.trace(LOG_TAG, "Set cluster URL to " + clusterURL.toASCIIString() + ", given input " + u.toASCIIString());
}
public void setClusterURL(URI u) {
setClusterURL(u, this.getPrefs());
this.clusterURL = u;
}
/**

View File

@ -7,7 +7,7 @@ package org.mozilla.gecko.sync.config;
import java.net.URI;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.GlobalSession;
import org.mozilla.gecko.sync.SyncConfiguration;
import org.mozilla.gecko.sync.net.AuthHeaderProvider;
import org.mozilla.gecko.sync.net.BaseResource;
import org.mozilla.gecko.sync.net.SyncStorageRecordRequest;
@ -27,22 +27,18 @@ public class ClientRecordTerminator {
super(); // Stop this class from being instantiated.
}
public static void deleteClientRecord(final String username,
final String clusterURL,
final String clientGuid,
final AuthHeaderProvider authHeaderProvider)
public static void deleteClientRecord(final SyncConfiguration config, final String clientGUID)
throws Exception {
// Would prefer to delegate to SyncConfiguration, but that would proliferate static methods.
final String collection = "clients";
final URI wboURI = new URI(clusterURL + GlobalSession.API_VERSION + "/" + username + "/storage/" + collection + "/" + clientGuid);
final URI wboURI = config.wboURI(collection, clientGUID);
// Would prefer to break this out into a self-contained client library.
final SyncStorageRecordRequest r = new SyncStorageRecordRequest(wboURI);
r.delegate = new SyncStorageRequestDelegate() {
@Override
public AuthHeaderProvider getAuthHeaderProvider() {
return authHeaderProvider;
return config.getAuthHeaderProvider();
}
@Override
@ -52,13 +48,13 @@ public class ClientRecordTerminator {
@Override
public void handleRequestSuccess(SyncStorageResponse response) {
Logger.info(LOG_TAG, "Deleted client record with GUID " + clientGuid + " from server.");
Logger.info(LOG_TAG, "Deleted client record with GUID " + clientGUID + " from server.");
BaseResource.consumeEntity(response);
}
@Override
public void handleRequestFailure(SyncStorageResponse response) {
Logger.warn(LOG_TAG, "Failed to delete client record with GUID " + clientGuid + " from server.");
Logger.warn(LOG_TAG, "Failed to delete client record with GUID " + clientGUID + " from server.");
try {
Logger.warn(LOG_TAG, "Server error message was: " + response.getErrorMessage());
} catch (Exception e) {
@ -71,7 +67,7 @@ public class ClientRecordTerminator {
public void handleRequestError(Exception ex) {
// It could be that we don't have network access when trying
// to remove an Account; not much to be done in this situation.
Logger.error(LOG_TAG, "Got exception trying to delete client record with GUID " + clientGuid + " from server; ignoring.", ex);
Logger.error(LOG_TAG, "Got exception trying to delete client record with GUID " + clientGUID + " from server; ignoring.", ex);
}
};

View File

@ -7,6 +7,7 @@ package org.mozilla.gecko.sync.receivers;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.background.common.GlobalConstants;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.Sync11Configuration;
import org.mozilla.gecko.sync.SyncConstants;
import org.mozilla.gecko.sync.SyncConfiguration;
import org.mozilla.gecko.sync.Utils;
@ -113,27 +114,29 @@ public class SyncAccountDeletedService extends IntentService {
return;
}
final String clientGuid = prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null);
final String clusterURL = prefs.getString(SyncConfiguration.PREF_CLUSTER_URL, null);
// Finally, a good place to do this.
prefs.edit().clear().commit();
if (clientGuid == null) {
Logger.warn(LOG_TAG, "Client GUID was null; not deleting client record from server.");
return;
}
if (clusterURL == null) {
Logger.warn(LOG_TAG, "Cluster URL was null; not deleting client record from server.");
return;
}
try {
ClientRecordTerminator.deleteClientRecord(encodedUsername, clusterURL, clientGuid, new BasicAuthHeaderProvider(encodedUsername, password));
} catch (Exception e) {
// This should never happen, but we really don't want to die in a background thread.
Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e);
final String clientGUID = prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null);
if (clientGUID == null) {
Logger.warn(LOG_TAG, "Client GUID was null; not deleting client record from server.");
return;
}
BasicAuthHeaderProvider authHeaderProvider = new BasicAuthHeaderProvider(encodedUsername, password);
SyncConfiguration configuration = new Sync11Configuration(encodedUsername, authHeaderProvider, prefs);
if (configuration.getClusterURL() == null) {
Logger.warn(LOG_TAG, "Cluster URL was null; not deleting client record from server.");
return;
}
try {
ClientRecordTerminator.deleteClientRecord(configuration, clientGUID);
} catch (Exception e) {
// This should never happen, but we really don't want to die in a background thread.
Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e);
}
} finally {
// Finally, a good place to do this.
prefs.edit().clear().commit();
}
}
}

View File

@ -24,7 +24,6 @@ public class Server11Repository extends Repository {
protected String collection;
protected URI collectionURI;
protected final AuthHeaderProvider authHeaderProvider;
public static final String VERSION_PATH_FRAGMENT = "1.1/";
/**
* Construct a new repository that fetches and stores against the Sync 1.1. API.

View File

@ -19,6 +19,7 @@ import org.mozilla.gecko.sync.GlobalSession;
import org.mozilla.gecko.sync.NonObjectJSONException;
import org.mozilla.gecko.sync.SharedPreferencesClientsDataDelegate;
import org.mozilla.gecko.sync.SharedPreferencesNodeAssignmentCallback;
import org.mozilla.gecko.sync.Sync11Configuration;
import org.mozilla.gecko.sync.SyncConfiguration;
import org.mozilla.gecko.sync.SyncConfigurationException;
import org.mozilla.gecko.sync.SyncConstants;
@ -527,8 +528,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter implements BaseGlob
final AuthHeaderProvider authHeaderProvider = new BasicAuthHeaderProvider(username, password);
final SharedPreferences prefs = getContext().getSharedPreferences(prefsPath, Utils.SHARED_PREFERENCES_MODE);
final SyncConfiguration config = new SyncConfiguration(username, authHeaderProvider, prefs);
config.syncKeyBundle = keyBundle;
final SyncConfiguration config = new Sync11Configuration(username, authHeaderProvider, prefs, keyBundle);
GlobalSession globalSession = new GlobalSession(config, this, this.mContext, extras, clientsDataDelegate, nodeAssignmentDelegate);
globalSession.start();