зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1253111 - Part 1: Introduce new sync stage to handle info/configuration r=rnewman
MozReview-Commit-ID: 7MOgR7A5SOF --HG-- extra : rebase_source : e029d60a063b2e1dd9061362c4d4a647263dd3ec
This commit is contained in:
Родитель
141464cd20
Коммит
29e4dd5c85
|
@ -893,6 +893,7 @@ sync_java_files = [TOPSRCDIR + '/mobile/android/services/src/main/java/org/mozil
|
|||
'sync/GlobalSession.java',
|
||||
'sync/HTTPFailureException.java',
|
||||
'sync/InfoCollections.java',
|
||||
'sync/InfoConfiguration.java',
|
||||
'sync/InfoCounts.java',
|
||||
'sync/JSONRecordFetcher.java',
|
||||
'sync/KeyBundleProvider.java',
|
||||
|
@ -1030,6 +1031,7 @@ sync_java_files = [TOPSRCDIR + '/mobile/android/services/src/main/java/org/mozil
|
|||
'sync/stage/EnsureCrypto5KeysStage.java',
|
||||
'sync/stage/FennecTabsServerSyncStage.java',
|
||||
'sync/stage/FetchInfoCollectionsStage.java',
|
||||
'sync/stage/FetchInfoConfigurationStage.java',
|
||||
'sync/stage/FetchMetaGlobalStage.java',
|
||||
'sync/stage/FormHistoryServerSyncStage.java',
|
||||
'sync/stage/GlobalSyncStage.java',
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.mozilla.gecko.sync.stage.CompletedStage;
|
|||
import org.mozilla.gecko.sync.stage.EnsureCrypto5KeysStage;
|
||||
import org.mozilla.gecko.sync.stage.FennecTabsServerSyncStage;
|
||||
import org.mozilla.gecko.sync.stage.FetchInfoCollectionsStage;
|
||||
import org.mozilla.gecko.sync.stage.FetchInfoConfigurationStage;
|
||||
import org.mozilla.gecko.sync.stage.FetchMetaGlobalStage;
|
||||
import org.mozilla.gecko.sync.stage.FormHistoryServerSyncStage;
|
||||
import org.mozilla.gecko.sync.stage.GlobalSyncStage;
|
||||
|
@ -177,6 +178,8 @@ public class GlobalSession implements HttpResponseObserver {
|
|||
stages.put(Stage.checkPreconditions, new CheckPreconditionsStage());
|
||||
stages.put(Stage.fetchInfoCollections, new FetchInfoCollectionsStage());
|
||||
stages.put(Stage.fetchMetaGlobal, new FetchMetaGlobalStage());
|
||||
stages.put(Stage.fetchInfoConfiguration, new FetchInfoConfigurationStage(
|
||||
config.infoConfigurationURL(), getAuthHeaderProvider()));
|
||||
stages.put(Stage.ensureKeysStage, new EnsureCrypto5KeysStage());
|
||||
|
||||
stages.put(Stage.syncClientsEngine, new SyncClientsEngineStage());
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/* 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 android.util.Log;
|
||||
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
|
||||
/**
|
||||
* Wraps and provides access to configuration data returned from info/configuration.
|
||||
* Docs: https://docs.services.mozilla.com/storage/apis-1.5.html#general-info
|
||||
*
|
||||
* - <bold>max_request_bytes</bold>: the maximum size in bytes of the overall
|
||||
* HTTP request body that will be accepted by the server.
|
||||
*
|
||||
* - <bold>max_post_records</bold>: the maximum number of records that can be
|
||||
* uploaded to a collection in a single POST request.
|
||||
*
|
||||
* - <bold>max_post_bytes</bold>: the maximum combined size in bytes of the
|
||||
* record payloads that can be uploaded to a collection in a single
|
||||
* POST request.
|
||||
*
|
||||
* - <bold>max_total_records</bold>: the maximum number of records that can be
|
||||
* uploaded to a collection as part of a batched upload.
|
||||
*
|
||||
* - <bold>max_total_bytes</bold>: the maximum combined size in bytes of the
|
||||
* record payloads that can be uploaded to a collection as part of
|
||||
* a batched upload.
|
||||
*/
|
||||
public class InfoConfiguration {
|
||||
private static final String LOG_TAG = "InfoConfiguration";
|
||||
|
||||
public static final String MAX_REQUEST_BYTES = "max_request_bytes";
|
||||
public static final String MAX_POST_RECORDS = "max_post_records";
|
||||
public static final String MAX_POST_BYTES = "max_post_bytes";
|
||||
public static final String MAX_TOTAL_RECORDS = "max_total_records";
|
||||
public static final String MAX_TOTAL_BYTES = "max_total_bytes";
|
||||
|
||||
private static final long DEFAULT_MAX_REQUEST_BYTES = 1048576;
|
||||
private static final long DEFAULT_MAX_POST_RECORDS = 100;
|
||||
private static final long DEFAULT_MAX_POST_BYTES = 1048576;
|
||||
private static final long DEFAULT_MAX_TOTAL_RECORDS = 10000;
|
||||
private static final long DEFAULT_MAX_TOTAL_BYTES = 104857600;
|
||||
|
||||
// While int's upper range is (2^31-1), which in bytes is equivalent to 2.147 GB, let's be optimistic
|
||||
// about the future and use long here, so that this code works if the server decides its clients are
|
||||
// all on fiber and have congress-library sized bookmark collections.
|
||||
// Record counts are long for the sake of simplicity.
|
||||
public final long maxRequestBytes;
|
||||
public final long maxPostRecords;
|
||||
public final long maxPostBytes;
|
||||
public final long maxTotalRecords;
|
||||
public final long maxTotalBytes;
|
||||
|
||||
public InfoConfiguration() {
|
||||
Logger.debug(LOG_TAG, "info/configuration is unavailable, using defaults");
|
||||
|
||||
maxRequestBytes = DEFAULT_MAX_REQUEST_BYTES;
|
||||
maxPostRecords = DEFAULT_MAX_POST_RECORDS;
|
||||
maxPostBytes = DEFAULT_MAX_POST_BYTES;
|
||||
maxTotalRecords = DEFAULT_MAX_TOTAL_RECORDS;
|
||||
maxTotalBytes = DEFAULT_MAX_TOTAL_BYTES;
|
||||
}
|
||||
|
||||
public InfoConfiguration(final ExtendedJSONObject record) {
|
||||
Logger.debug(LOG_TAG, "info/configuration is " + record.toJSONString());
|
||||
|
||||
maxRequestBytes = getValueFromRecord(record, MAX_REQUEST_BYTES, DEFAULT_MAX_REQUEST_BYTES);
|
||||
maxPostRecords = getValueFromRecord(record, MAX_POST_RECORDS, DEFAULT_MAX_POST_RECORDS);
|
||||
maxPostBytes = getValueFromRecord(record, MAX_POST_BYTES, DEFAULT_MAX_POST_BYTES);
|
||||
maxTotalRecords = getValueFromRecord(record, MAX_TOTAL_RECORDS, DEFAULT_MAX_TOTAL_RECORDS);
|
||||
maxTotalBytes = getValueFromRecord(record, MAX_TOTAL_BYTES, DEFAULT_MAX_TOTAL_BYTES);
|
||||
}
|
||||
|
||||
private static Long getValueFromRecord(ExtendedJSONObject record, String key, long defaultValue) {
|
||||
if (!record.containsKey(key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try {
|
||||
Long val = record.getLong(key);
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return val;
|
||||
} catch (NumberFormatException e) {
|
||||
Log.w(LOG_TAG, "Could not parse key " + key + " from record: " + record, e);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,6 +30,8 @@ public class SyncConfiguration {
|
|||
public URI clusterURL;
|
||||
public KeyBundle syncKeyBundle;
|
||||
|
||||
public InfoConfiguration infoConfiguration;
|
||||
|
||||
public CollectionKeys collectionKeys;
|
||||
public InfoCollections infoCollections;
|
||||
public MetaGlobal metaGlobal;
|
||||
|
@ -366,6 +368,10 @@ public class SyncConfiguration {
|
|||
return infoBaseURL() + "collections";
|
||||
}
|
||||
|
||||
public String infoConfigurationURL() {
|
||||
return infoBaseURL() + "configuration";
|
||||
}
|
||||
|
||||
public String infoCollectionCountsURL() {
|
||||
return infoBaseURL() + "collection_counts";
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import org.mozilla.gecko.sync.net.SyncStorageResponse;
|
|||
|
||||
/**
|
||||
* A fairly generic delegate to handle fetches of single JSON object blobs, as
|
||||
* provided by <code>info/collections</code> and <code>info/collection_counts</code>.
|
||||
* provided by <code>info/configuration</code>, <code>info/collections</code>
|
||||
* and <code>info/collection_counts</code>.
|
||||
*/
|
||||
public interface JSONRecordFetchDelegate {
|
||||
public void handleSuccess(ExtendedJSONObject body);
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/* 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.stage;
|
||||
|
||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||
import org.mozilla.gecko.sync.InfoConfiguration;
|
||||
import org.mozilla.gecko.sync.JSONRecordFetcher;
|
||||
import org.mozilla.gecko.sync.delegates.JSONRecordFetchDelegate;
|
||||
import org.mozilla.gecko.sync.net.AuthHeaderProvider;
|
||||
import org.mozilla.gecko.sync.net.SyncStorageResponse;
|
||||
|
||||
/**
|
||||
* Fetches configuration data from info/configurations endpoint.
|
||||
*/
|
||||
public class FetchInfoConfigurationStage extends AbstractNonRepositorySyncStage {
|
||||
private final String configurationURL;
|
||||
private final AuthHeaderProvider authHeaderProvider;
|
||||
|
||||
public FetchInfoConfigurationStage(final String configurationURL, final AuthHeaderProvider authHeaderProvider) {
|
||||
super();
|
||||
this.configurationURL = configurationURL;
|
||||
this.authHeaderProvider = authHeaderProvider;
|
||||
}
|
||||
|
||||
public class StageInfoConfigurationDelegate implements JSONRecordFetchDelegate {
|
||||
@Override
|
||||
public void handleSuccess(final ExtendedJSONObject result) {
|
||||
session.config.infoConfiguration = new InfoConfiguration(result);
|
||||
session.advance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFailure(final SyncStorageResponse response) {
|
||||
// Handle all non-404 failures upstream.
|
||||
if (response.getStatusCode() != 404) {
|
||||
session.handleHTTPError(response, "Failure fetching info/configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
// End-point might not be available (404) if server is running an older version.
|
||||
// We will use default config values in this case.
|
||||
session.config.infoConfiguration = new InfoConfiguration();
|
||||
session.advance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleError(final Exception e) {
|
||||
session.abort(e, "Failure fetching info/configuration");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void execute() {
|
||||
final StageInfoConfigurationDelegate delegate = new StageInfoConfigurationDelegate();
|
||||
final JSONRecordFetcher fetcher = new JSONRecordFetcher(configurationURL, authHeaderProvider);
|
||||
fetcher.fetch(delegate);
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ public interface GlobalSyncStage {
|
|||
idle, // Start state.
|
||||
checkPreconditions, // Preparation of the basics. TODO: clear status
|
||||
fetchInfoCollections, // Take a look at timestamps.
|
||||
fetchInfoConfiguration, // Fetch server upload limits
|
||||
fetchMetaGlobal,
|
||||
ensureKeysStage,
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче