public OAuth2Authentication readAuthenticationForRefreshToken(String value) {
    OAuth2Authentication authentication = null;

    try {
      authentication =
          dynamoDBTemplate.get(
              schema.getRefreshTableName(),
              Collections.singletonMap(
                  schema.getRefreshColumnTokenId(), new AttributeValue(extractTokenKey(value))),
              new ObjectExtractor<OAuth2Authentication>() {

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

    return authentication;
  }
  public OAuth2AccessToken readAccessToken(String tokenValue) {
    OAuth2AccessToken accessToken = null;

    try {
      accessToken =
          dynamoDBTemplate.get(
              schema.getAccessTableName(),
              Collections.singletonMap(
                  schema.getAccessColumnTokenId(), new AttributeValue(extractTokenKey(tokenValue))),
              new ObjectExtractor<OAuth2AccessToken>() {

                public OAuth2AccessToken extract(Map<String, AttributeValue> values) {
                  return deserializeAccessToken(values.get(schema.getAccessColumnToken()).getB());
                }
              },
              schema.getAccessColumnToken());
    } catch (EmptyResultDataAccessException e) {
      if (LOG.isInfoEnabled()) {
        LOG.info("Failed to find access token for token " + tokenValue);
      }
    } catch (IllegalArgumentException e) {
      LOG.warn("Failed to deserialize access token for " + tokenValue, e);
      removeAccessToken(tokenValue);
    }

    return accessToken;
  }
  public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
    OAuth2AccessToken accessToken = null;

    String key = authenticationKeyGenerator.extractKey(authentication);
    try {
      String accessTokenId =
          dynamoDBTemplate.queryUnique(
              schema.getAccessTableName(),
              schema.getAccessIndexAuthenticationId(), //
              Collections.singletonMap(
                  schema.getAccessColumnAuthenticationId(),
                  new Condition()
                      .withComparisonOperator(ComparisonOperator.EQ)
                      .withAttributeValueList(new AttributeValue(key))), //
              new ObjectExtractor<String>() {

                public String extract(Map<String, AttributeValue> values) {
                  return values.get(schema.getAccessColumnTokenId()).getS();
                }
              });
      accessToken =
          dynamoDBTemplate.get(
              schema.getAccessTableName(),
              Collections.singletonMap(
                  schema.getAccessColumnTokenId(), new AttributeValue(accessTokenId)),
              new ObjectExtractor<OAuth2AccessToken>() {

                public OAuth2AccessToken extract(Map<String, AttributeValue> values) {
                  return deserializeAccessToken(values.get(schema.getAccessColumnToken()).getB());
                }
              });
    } catch (EmptyResultDataAccessException | IncorrectResultSizeDataAccessException e) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Failed to find access token for authentication " + authentication);
      }
    } catch (IllegalArgumentException e) {
      LOG.error("Could not extract access token for authentication " + authentication, e);
    }

    if (accessToken != null
        && !key.equals(
            authenticationKeyGenerator.extractKey(readAuthentication(accessToken.getValue())))) {
      // Keep the store consistent (maybe the same user is represented by this authentication but
      // the details have
      // changed)
      storeAccessToken(accessToken, authentication);
    }
    return accessToken;
  }