public APIResourceCredentials saveResourceCredentials(
     LocalUserDetail user, APIResourceCredentials resourceCredentials) {
   if (null == credentialsCache) {
     return null;
   }
   return credentialsCache.saveResourceCredentials(user, resourceCredentials);
 }
 public Object getCollectionForDate(LocalUserDetail user, LocalDate date, APICollectionType type)
     throws FitbitAPIException {
   // Get cache key for collection:
   String cacheKey = getCacheKey(date, type);
   // Get the resource credentials:
   APIResourceCredentials credentials = credentialsCache.getResourceCredentials(user);
   // First consult the cache:
   Object result = getFromCache(user, credentials, cacheKey);
   // If not in cache, retrieve from the API service and place in cache:
   if (null == result) {
     result = client.getCollectionForDate(user, FitbitUser.CURRENT_AUTHORIZED_USER, type, date);
     putInCache(result, credentials, cacheKey);
   }
   return result;
 }
 public APIResourceCredentials expireResourceCredentials(LocalUserDetail user) {
   if (null == credentialsCache) {
     return null;
   }
   return credentialsCache.expireResourceCredentials(user);
 }
 public APIResourceCredentials getResourceCredentialsByTempToken(String tempToken) {
   if (null == credentialsCache) {
     return null;
   }
   return credentialsCache.getResourceCredentialsByTempToken(tempToken);
 }
 public APIResourceCredentials getResourceCredentialsByUser(LocalUserDetail user) {
   if (null == credentialsCache) {
     return null;
   }
   return credentialsCache.getResourceCredentials(user);
 }
  public void evictUpdatedResourcesFromCache(
      String subscriberId, InputStream updateMessageStream, String serverSignature)
      throws FitbitAPIException {
    try {
      if (null == serverSignature) {
        throw new FitbitAPISecurityException("Missing signature.");
      }

      String updateMessage = APIUtil.inputStreamToString(updateMessageStream);

      String ourSignature = APIUtil.generateSignature(updateMessage, subscriberSecret);
      if (null == ourSignature || !ourSignature.equals(serverSignature)) {
        throw new FitbitAPISecurityException("Signatures do not match, given " + serverSignature);
      }

      UpdateNotification notification = new UpdateNotification(new JSONArray(updateMessage));

      int i = 0;
      for (UpdatedResource resource : notification.getUpdatedResources()) {
        //noinspection UnnecessaryParentheses,ValueOfIncrementOrDecrementUsed
        log.info(
            "Processing update notification "
                + (++i)
                + " for subscription "
                + resource.getSubscriptionId());

        LocalSubscriptionDetail sub =
            subscriptionStore.getBySubscriptionId(resource.getSubscriptionId());
        if (null == sub) {
          log.info(
              "Nothing known about subscription "
                  + resource.getSubscriptionId()
                  + ", creating placeholder.");

          sub =
              new LocalSubscriptionDetail(
                  new SubscriptionDetail(
                      subscriberId,
                      resource.getSubscriptionId(),
                      resource.getOwner(),
                      resource.getCollectionType()),
                  false);
          subscriptionStore.save(sub);
        }

        sub.setLastUpdateNotificationDate(new Date());

        APIResourceCredentials credentials =
            credentialsCache.getResourceCredentials(
                new LocalUserDetail(resource.getSubscriptionId()));

        String cacheKeyWithUserId =
            APIUtil.constructFullUrl(
                client.getApiBaseUrl(),
                client.getApiVersion(),
                resource.getOwner(),
                resource.getCollectionType(),
                resource.getDate(),
                APIFormat.JSON);

        Activities entity = (Activities) entityCache.get(credentials, cacheKeyWithUserId);
        if (null != entity) {
          log.info("Evicting entity " + cacheKeyWithUserId);
          entityCache.remove(credentials, cacheKeyWithUserId);
        } else {
          log.info("There is no cached version of entity " + cacheKeyWithUserId);
        }

        String cacheKeyWithPlaceholder =
            APIUtil.constructFullUrl(
                client.getApiBaseUrl(),
                client.getApiVersion(),
                FitbitUser.CURRENT_AUTHORIZED_USER,
                resource.getCollectionType(),
                resource.getDate(),
                APIFormat.JSON);

        entity = (Activities) entityCache.get(credentials, cacheKeyWithPlaceholder);
        if (null != entity) {
          log.info("Evicting entity " + cacheKeyWithPlaceholder);
          entityCache.remove(credentials, cacheKeyWithPlaceholder);
        } else {
          log.info("There is no cached version of entity " + cacheKeyWithPlaceholder);
        }
      }
    } catch (IOException e) {
      throw new FitbitAPIException("Notification stream is malformed: " + e, e);
    } catch (JSONException e) {
      throw new FitbitAPIException("Unable to parse update message: " + e, e);
    }
  }