コード例 #1
0
  public GlobalSession(
      SyncConfiguration config,
      BaseGlobalSessionCallback callback,
      Context context,
      Bundle extras,
      ClientsDataDelegate clientsDelegate,
      NodeAssignmentCallback nodeAssignmentCallback)
      throws SyncConfigurationException, IllegalArgumentException, IOException, ParseException,
          NonObjectJSONException {

    if (callback == null) {
      throw new IllegalArgumentException("Must provide a callback to GlobalSession constructor.");
    }

    Logger.debug(LOG_TAG, "GlobalSession initialized with bundle " + extras);

    this.callback = callback;
    this.context = context;
    this.clientsDelegate = clientsDelegate;
    this.nodeAssignmentCallback = nodeAssignmentCallback;

    this.config = config;
    registerCommands();
    prepareStages();

    Collection<String> knownStageNames = SyncConfiguration.validEngineNames();
    config.stagesToSync = Utils.getStagesToSyncFromBundle(knownStageNames, extras);

    // TODO: data-driven plan for the sync, referring to prepareStages.
  }
コード例 #2
0
  /**
   * Engines to include in a fresh meta/global record.
   *
   * <p>Returns either the persisted engine names (perhaps we have been node re-assigned and are
   * initializing a clean server: we want to upload the persisted engine names so that we don't
   * accidentally disable engines that Android Sync doesn't recognize), or the set of engines names
   * that Android Sync implements.
   *
   * @return set of engine names.
   */
  protected Set<String> enabledEngineNames() {
    if (config.enabledEngineNames != null) {
      return config.enabledEngineNames;
    }

    // These are the default set of engine names.
    Set<String> validEngineNames = SyncConfiguration.validEngineNames();

    // If the user hasn't set any selected engines, that's okay -- default to
    // everything.
    if (config.userSelectedEngines == null) {
      return validEngineNames;
    }

    // userSelectedEngines has keys that are engine names, and boolean values
    // corresponding to whether the user asked for the engine to sync or not. If
    // an engine is not present, that means the user didn't change its sync
    // setting. Since we default to everything on, that means the user didn't
    // turn it off; therefore, it's included in the set of engines to sync.
    Set<String> validAndSelectedEngineNames = new HashSet<String>();
    for (String engineName : validEngineNames) {
      if (config.userSelectedEngines.containsKey(engineName)
          && !config.userSelectedEngines.get(engineName)) {
        continue;
      }
      validAndSelectedEngineNames.add(engineName);
    }
    return validAndSelectedEngineNames;
  }
コード例 #3
0
  /** Perform appropriate backoff etc. extraction. */
  public void interpretHTTPFailure(HttpResponse response) {
    // TODO: handle permanent rejection.
    long responseBackoff = (new SyncResponse(response)).totalBackoffInMilliseconds();
    if (responseBackoff > 0) {
      callback.requestBackoff(responseBackoff);
    }

    if (response.getStatusLine() != null) {
      final int statusCode = response.getStatusLine().getStatusCode();
      switch (statusCode) {
        case 400:
          SyncStorageResponse storageResponse = new SyncStorageResponse(response);
          this.interpretHTTPBadRequestBody(storageResponse);
          break;

        case 401:
          /*
           * Alert our callback we have a 401 on a cluster URL. This GlobalSession
           * will fail, but the next one will fetch a new cluster URL and will
           * distinguish between "node reassignment" and "user password changed".
           */
          callback.informUnauthorizedResponse(this, config.getClusterURL());
          break;
      }
    }
  }
コード例 #4
0
  protected void wipeServer(
      final AuthHeaderProvider authHeaderProvider, final WipeServerDelegate wipeDelegate) {
    SyncStorageRequest request;
    final GlobalSession self = this;

    try {
      request = new SyncStorageRequest(config.storageURL());
    } catch (URISyntaxException ex) {
      Logger.warn(LOG_TAG, "Invalid URI in wipeServer.");
      wipeDelegate.onWipeFailed(ex);
      return;
    }

    request.delegate =
        new SyncStorageRequestDelegate() {

          @Override
          public String ifUnmodifiedSince() {
            return null;
          }

          @Override
          public void handleRequestSuccess(SyncStorageResponse response) {
            BaseResource.consumeEntity(response);
            wipeDelegate.onWiped(response.normalizedWeaveTimestamp());
          }

          @Override
          public void handleRequestFailure(SyncStorageResponse response) {
            Logger.warn(
                LOG_TAG, "Got request failure " + response.getStatusCode() + " in wipeServer.");
            // Process HTTP failures here to pick up backoffs, etc.
            self.interpretHTTPFailure(response.httpResponse());
            BaseResource.consumeEntity(
                response); // The exception thrown should not need the body of the response.
            wipeDelegate.onWipeFailed(new HTTPFailureException(response));
          }

          @Override
          public void handleRequestError(Exception ex) {
            Logger.warn(LOG_TAG, "Got exception in wipeServer.", ex);
            wipeDelegate.onWipeFailed(ex);
          }

          @Override
          public AuthHeaderProvider getAuthHeaderProvider() {
            return GlobalSession.this.getAuthHeaderProvider();
          }
        };
    request.delete();
  }
コード例 #5
0
 public URI wboURI(String collection, String id) throws URISyntaxException {
   return config.wboURI(collection, id);
 }
コード例 #6
0
 /*
  * Config passthrough for convenience.
  */
 public AuthHeaderProvider getAuthHeaderProvider() {
   return config.getAuthHeaderProvider();
 }
コード例 #7
0
 /*
  * Key accessors.
  */
 public KeyBundle keyBundleForCollection(String collection) throws NoCollectionKeysSetException {
   return config.getCollectionKeys().keyBundleForCollection(collection);
 }
コード例 #8
0
  /*
   * meta/global callbacks.
   */
  public void processMetaGlobal(MetaGlobal global) {
    config.metaGlobal = global;

    Long storageVersion = global.getStorageVersion();
    if (storageVersion == null) {
      Logger.warn(
          LOG_TAG, "Malformed remote meta/global: could not retrieve remote storage version.");
      freshStart();
      return;
    }
    if (storageVersion < STORAGE_VERSION) {
      Logger.warn(
          LOG_TAG,
          "Outdated server: reported "
              + "remote storage version "
              + storageVersion
              + " < "
              + "local storage version "
              + STORAGE_VERSION);
      freshStart();
      return;
    }
    if (storageVersion > STORAGE_VERSION) {
      Logger.warn(
          LOG_TAG,
          "Outdated client: reported "
              + "remote storage version "
              + storageVersion
              + " > "
              + "local storage version "
              + STORAGE_VERSION);
      requiresUpgrade();
      return;
    }
    String remoteSyncID = global.getSyncID();
    if (remoteSyncID == null) {
      Logger.warn(LOG_TAG, "Malformed remote meta/global: could not retrieve remote syncID.");
      freshStart();
      return;
    }
    String localSyncID = config.syncID;
    if (!remoteSyncID.equals(localSyncID)) {
      Logger.warn(
          LOG_TAG,
          "Remote syncID different from local syncID: resetting client and assuming remote syncID.");
      resetAllStages();
      config.purgeCryptoKeys();
      config.syncID = remoteSyncID;
    }
    // Compare lastModified timestamps for remote/local engine selection times.
    Logger.debug(
        LOG_TAG,
        "Comparing local engine selection timestamp ["
            + config.userSelectedEnginesTimestamp
            + "] to server meta/global timestamp ["
            + config.persistedMetaGlobal().lastModified()
            + "].");
    if (config.userSelectedEnginesTimestamp < config.persistedMetaGlobal().lastModified()) {
      // Remote has later meta/global timestamp. Don't upload engine changes.
      config.userSelectedEngines = null;
    }
    // Persist enabled engine names.
    config.enabledEngineNames = global.getEnabledEngineNames();
    if (config.enabledEngineNames == null) {
      Logger.warn(LOG_TAG, "meta/global reported no enabled engine names!");
    } else {
      if (Logger.shouldLogVerbose(LOG_TAG)) {
        Logger.trace(
            LOG_TAG,
            "Persisting enabled engine names '"
                + Utils.toCommaSeparatedString(config.enabledEngineNames)
                + "' from meta/global.");
      }
    }
    config.persistToPrefs();
    advance();
  }
コード例 #9
0
 public void fetchInfoCollections(JSONRecordFetchDelegate callback) throws URISyntaxException {
   final JSONRecordFetcher fetcher =
       new JSONRecordFetcher(config.infoCollectionsURL(), getAuthHeaderProvider());
   fetcher.fetch(callback);
 }