Skip to content

Commit

Permalink
Merge 0144d13 into a4132cb
Browse files Browse the repository at this point in the history
  • Loading branch information
mook-as committed Feb 9, 2018
2 parents a4132cb + 0144d13 commit 353cc63
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.cloudfoundry.identity.uaa.util.UaaStringUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DeadlockLoserDataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
Expand Down Expand Up @@ -215,12 +216,14 @@ protected void performExpirationClean() {
//check if we should expire again
if ((System.currentTimeMillis()-last) > getExpirationTime()) {
//avoid concurrent deletes from the same UAA - performance improvement
if (lastClean.compareAndSet(last, last+getExpirationTime())) {
if (lastClean.compareAndSet(last, last+getExpirationTime())) try {
JdbcTemplate template = new JdbcTemplate(dataSource);
int expired = template.update(SQL_EXPIRE_STATEMENT, System.currentTimeMillis());
logger.debug("[oauth_code] Removed "+expired+" expired entries.");
expired = template.update(SQL_CLEAN_STATEMENT, new Timestamp(System.currentTimeMillis()-LEGACY_CODE_EXPIRATION_TIME));
logger.debug("[oauth_code] Removed "+expired+" old entries.");
} catch (DeadlockLoserDataAccessException e) {
logger.debug("[oauth code] Deadlock trying to expire entries, ignored.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.junit.Before;
import org.junit.Test;
import org.springframework.dao.DeadlockLoserDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
Expand All @@ -44,6 +45,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Timestamp;
Expand Down Expand Up @@ -314,6 +316,27 @@ public void testCleanUpUnusedOldTokens_MySQL_In_Another_Timezone() throws Except
}
}

@Test
public void testCleanUpExpiredTokensDeadlockLoser() throws Exception {
Connection con = dataSource.getConnection();
try {
Connection expirationLoser = (Connection) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[]{Connection.class},
new ExpirationLoserConnection(con));

SameConnectionDataSource sameConnectionDataSource = new SameConnectionDataSource(expirationLoser);

store = new UaaTokenStore(sameConnectionDataSource, 1);
int count = 10;
for (int i=0; i<count; i++) {
String code = store.createAuthorizationCode(clientAuthentication);
store.consumeAuthorizationCode(code);
}
} finally {
con.close();
store = new UaaTokenStore(dataSource);
}
}


public class SameConnectionDataSource implements DataSource {
Expand Down Expand Up @@ -387,5 +410,52 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
}
}

public class ExpirationLoserConnection implements InvocationHandler {
static final String CLOSE_VAL = "close";
static final String PREPARE_VAL = "prepareStatement";
private final Connection con;

protected class ExpirationLoserPreparedStatement implements InvocationHandler {
static final String UPDATE_VAL = "executeUpdate";
private final PreparedStatement stmt;

ExpirationLoserPreparedStatement(PreparedStatement stmt) {
this.stmt = stmt;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (UPDATE_VAL.equals(method.getName())) {
throw new DeadlockLoserDataAccessException("Deadlock in update (emulated)", null);
}
return method.invoke(stmt, args);
}
}

ExpirationLoserConnection(Connection con) {
this.con = con;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case CLOSE_VAL:
// This breaks things
return null;
case PREPARE_VAL:
if (args.length > 0) {
String sql = (String) args[0];
if (sql.startsWith("delete from oauth_code where expiresat ")) {
PreparedStatement stmt = (PreparedStatement) method.invoke(con, args);
return Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[]{PreparedStatement.class},
new ExpirationLoserPreparedStatement(stmt));
}
}
}
return method.invoke(con, args);
}
}

private static final byte[] UAA_AUTHENTICATION_DATA_OLD_STYLE = new byte[] {123, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 114, 101, 115, 112, 111, 110, 115, 101, 84, 121, 112, 101, 115, 34, 58, 91, 93, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 114, 101, 115, 111, 117, 114, 99, 101, 73, 100, 115, 34, 58, 91, 93, 44, 34, 117, 115, 101, 114, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 46, 117, 97, 97, 80, 114, 105, 110, 99, 105, 112, 97, 108, 34, 58, 34, 123, 92, 34, 105, 100, 92, 34, 58, 92, 34, 117, 115, 101, 114, 105, 100, 92, 34, 44, 92, 34, 110, 97, 109, 101, 92, 34, 58, 92, 34, 117, 115, 101, 114, 110, 97, 109, 101, 92, 34, 44, 92, 34, 101, 109, 97, 105, 108, 92, 34, 58, 92, 34, 117, 115, 101, 114, 110, 97, 109, 101, 64, 116, 101, 115, 116, 46, 111, 114, 103, 92, 34, 44, 92, 34, 111, 114, 105, 103, 105, 110, 92, 34, 58, 92, 34, 117, 97, 97, 92, 34, 44, 92, 34, 101, 120, 116, 101, 114, 110, 97, 108, 73, 100, 92, 34, 58, 110, 117, 108, 108, 44, 92, 34, 122, 111, 110, 101, 73, 100, 92, 34, 58, 92, 34, 117, 97, 97, 92, 34, 125, 34, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 114, 101, 113, 117, 101, 115, 116, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 58, 123, 34, 103, 114, 97, 110, 116, 95, 116, 121, 112, 101, 34, 58, 34, 112, 97, 115, 115, 119, 111, 114, 100, 34, 44, 34, 99, 108, 105, 101, 110, 116, 95, 105, 100, 34, 58, 34, 99, 108, 105, 101, 110, 116, 105, 100, 34, 44, 34, 115, 99, 111, 112, 101, 34, 58, 34, 111, 112, 101, 110, 105, 100, 34, 125, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 114, 101, 100, 105, 114, 101, 99, 116, 85, 114, 105, 34, 58, 110, 117, 108, 108, 44, 34, 117, 115, 101, 114, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 46, 97, 117, 116, 104, 111, 114, 105, 116, 105, 101, 115, 34, 58, 91, 34, 111, 112, 101, 110, 105, 100, 34, 93, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 97, 117, 116, 104, 111, 114, 105, 116, 105, 101, 115, 34, 58, 91, 34, 111, 97, 117, 116, 104, 46, 108, 111, 103, 105, 110, 34, 93, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 99, 108, 105, 101, 110, 116, 73, 100, 34, 58, 34, 99, 108, 105, 101, 110, 116, 105, 100, 34, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 97, 112, 112, 114, 111, 118, 101, 100, 34, 58, 116, 114, 117, 101, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 115, 99, 111, 112, 101, 34, 58, 91, 34, 111, 112, 101, 110, 105, 100, 34, 93, 125};
}

0 comments on commit 353cc63

Please sign in to comment.