/**
  * Obtain a new access token for the specified resource using the refresh token.
  *
  * @param resource The resource.
  * @param refreshToken The refresh token.
  * @return The access token, or null if failed.
  */
 protected OAuth2AccessToken obtainAccessToken(
     OAuth2ProtectedResourceDetails resource, OAuth2RefreshToken refreshToken) {
   MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
   form.add("grant_type", "refresh_token");
   form.add("refresh_token", refreshToken.getValue());
   return retrieveToken(form, resource);
 }
 @Override
 public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
   OAuth2AuthenticationAccessToken oAuth2AuthenticationAccessToken =
       oAuth2AccessTokenRepository.findByRefreshToken(refreshToken.getValue());
   if (oAuth2AuthenticationAccessToken != null) {
     oAuth2AccessTokenRepository.delete(oAuth2AuthenticationAccessToken);
   }
 }
 @Override
 public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
   /*Query query = new Query();
   query.addCriteria(Criteria.where("tokenId").is(token.getValue()));
   OAuth2AuthenticationRefreshToken auth2AuthenticationRefreshToken = mongoTemplate.findOne(query, OAuth2AuthenticationRefreshToken.class, "oauth2_refresh_token");*/
   OAuth2AuthenticationRefreshToken auth2AuthenticationRefreshToken =
       oAuth2RefreshTokenDao.findByTokenId(token.getValue());
   return auth2AuthenticationRefreshToken.getAuthentication();
 }
 @Override
 public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
   /*Query query = new Query();
   query.addCriteria(Criteria.where("refreshToken").is(refreshToken.getValue()));
   OAuth2AuthenticationAccessToken token = mongoTemplate.findOne(query, OAuth2AuthenticationAccessToken.class, "oauth2_access_token");*/
   OAuth2AuthenticationAccessToken token =
       oAuth2AccessTokenDao.findByRefreshToken(refreshToken.getValue());
   if (token != null) {
     oAuth2AccessTokenDao.delete(token);
   }
 }
 @Test
 public void testDifferentRefreshTokenMaintainsState() throws Exception {
   // create access token
   getTokenServices().setAccessTokenValiditySeconds(1);
   getTokenServices()
       .setClientDetailsService(
           new ClientDetailsService() {
             public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception {
               BaseClientDetails client = new BaseClientDetails();
               client.setAccessTokenValiditySeconds(1);
               return client;
             }
           });
   OAuth2Authentication expectedAuthentication =
       new OAuth2Authentication(
           new AuthorizationRequest("id", Collections.singleton("read"), null, null),
           new TestAuthentication("test2", false));
   DefaultOAuth2AccessToken firstAccessToken =
       (DefaultOAuth2AccessToken) getTokenServices().createAccessToken(expectedAuthentication);
   OAuth2RefreshToken expectedExpiringRefreshToken = firstAccessToken.getRefreshToken();
   // Make it expire (and rely on mutable state in volatile token store)
   firstAccessToken.setExpiration(new Date(System.currentTimeMillis() - 1000));
   // create another access token
   OAuth2AccessToken secondAccessToken =
       getTokenServices().createAccessToken(expectedAuthentication);
   assertFalse(
       "The new access token should be different",
       firstAccessToken.getValue().equals(secondAccessToken.getValue()));
   assertEquals(
       "The new access token should have the same refresh token",
       expectedExpiringRefreshToken.getValue(),
       secondAccessToken.getRefreshToken().getValue());
   // refresh access token with refresh token
   getTokenServices()
       .refreshAccessToken(
           expectedExpiringRefreshToken.getValue(),
           expectedAuthentication.getAuthorizationRequest().getScope());
   assertEquals(1, getAccessTokenCount());
 }
  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);
  }
 @Override
 public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
   oAuth2AccessTokenRepository.delete(
       oAuth2AccessTokenRepository.findByRefreshToken(refreshToken.getValue()));
 }
 @Override
 public void removeRefreshToken(OAuth2RefreshToken token) {
   oAuth2RefreshTokenRepository.delete(
       oAuth2RefreshTokenRepository.findByTokenId(token.getValue()));
 }
 @Override
 public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
   return oAuth2RefreshTokenRepository.findByTokenId(token.getValue()).getAuthentication();
 }
 public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
   removeAccessTokenUsingRefreshToken(refreshToken.getValue());
 }
 public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
   return readAuthenticationForRefreshToken(token.getValue());
 }
 public void removeRefreshToken(OAuth2RefreshToken token) {
   removeRefreshToken(token.getValue());
 }