public OAuth2RefreshToken readRefreshToken(String token) {
    OAuth2RefreshToken refreshToken = null;

    try {
      refreshToken =
          dynamoDBTemplate.get(
              schema.getRefreshTableName(),
              Collections.singletonMap(
                  schema.getRefreshColumnTokenId(), new AttributeValue(extractTokenKey(token))),
              new ObjectExtractor<OAuth2RefreshToken>() {

                public OAuth2RefreshToken extract(Map<String, AttributeValue> values) {
                  return deserializeRefreshToken(values.get(schema.getRefreshColumnToken()).getB());
                }
              },
              schema.getRefreshColumnToken());
    } catch (EmptyResultDataAccessException e) {
      if (LOG.isInfoEnabled()) {
        LOG.info("Failed to find refresh token for token " + token);
      }
    } catch (IllegalArgumentException e) {
      LOG.warn("Failed to deserialize refresh token for token " + token, e);
      removeRefreshToken(token);
    }

    return refreshToken;
  }
  public void storeRefreshToken(
      OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
    Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
    updates.put(
        schema.getRefreshColumnToken(),
        new AttributeValueUpdate(
            new AttributeValue().withB(serializeRefreshToken(refreshToken)), AttributeAction.PUT));
    updates.put(
        schema.getRefreshColumnAuthentication(),
        new AttributeValueUpdate(
            new AttributeValue().withB(serializeAuthentication(authentication)),
            AttributeAction.PUT));

    dynamoDBTemplate.update(
        schema.getRefreshTableName(), //
        Collections.singletonMap(
            schema.getRefreshColumnTokenId(),
            new AttributeValue(extractTokenKey(refreshToken.getValue()))), //
        updates);
  }