Skip to content

Commit

Permalink
cache node_security table for fast authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
erilong committed Sep 3, 2008
1 parent ee82fdb commit 0513a3f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
Expand Up @@ -39,6 +39,8 @@ public interface INodeService {
public void ignoreNodeChannelForExternalId(boolean ignore, String channelId, String nodeGroupId, String externalId);

public boolean isNodeAuthorized(String nodeId, String password);

public void flushNodeAuthorizedCache();

public boolean isRegistrationEnabled(String nodeId);

Expand Down
Expand Up @@ -27,7 +27,9 @@
import java.sql.Types;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand All @@ -36,15 +38,23 @@
import org.jumpmind.symmetric.model.Node;
import org.jumpmind.symmetric.model.NodeSecurity;
import org.jumpmind.symmetric.service.INodeService;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;

public class NodeService extends AbstractService implements INodeService {

@SuppressWarnings("unused")
private static final Log logger = LogFactory.getLog(NodeService.class);


private static final long MAX_SECURITY_CACHE_TIME = 60000;

private Node nodeIdentity;

private Map<String, NodeSecurity> securityCache;

private long securityCacheTime;

/**
* Lookup a node in the database, which contains information for syncing
* with it.
Expand Down Expand Up @@ -101,6 +111,7 @@ public NodeSecurity findNodeSecurity(String id, boolean createIfNotFound) {
}

public void insertNodeSecurity(String id) {
flushNodeAuthorizedCache();
jdbcTemplate.update(getSql("insertNodeSecuritySql"), new Object[] { id, generatePassword() });
}

Expand All @@ -123,15 +134,27 @@ protected <T> T getFirstEntry(List<T> list) {
* Check that the given node and password match in the node_security table.
* A node must authenticate before it's allowed to sync data.
*/
@SuppressWarnings("unchecked")
public boolean isNodeAuthorized(String id, String password) {
NodeSecurity nodeSecurity = findNodeSecurity(id);
if (System.currentTimeMillis() - securityCacheTime >= MAX_SECURITY_CACHE_TIME
|| securityCacheTime == 0) {
securityCache = (Map<String, NodeSecurity>) jdbcTemplate.query(getSql("findAllNodeSecuritySql"),
new NodeSecurityResultSetExtractor());
securityCacheTime = System.currentTimeMillis();
}

NodeSecurity nodeSecurity = securityCache.get(id);
if (nodeSecurity != null
&& ((nodeSecurity.getPassword() != null && !nodeSecurity.getPassword().equals("") && nodeSecurity
.getPassword().equals(password)) || nodeSecurity.isRegistrationEnabled())) {
return true;
}
return false;
}

public void flushNodeAuthorizedCache() {
securityCacheTime = 0;
}

public Node findIdentity() {
return findIdentity(true);
Expand Down Expand Up @@ -177,6 +200,7 @@ public List<Node> findTargetNodesFor(DataEventAction eventAction) {
}

public boolean updateNodeSecurity(NodeSecurity security) {
flushNodeAuthorizedCache();
return jdbcTemplate.update(getSql("updateNodeSecuritySql"), new Object[] { security.getPassword(),
security.isRegistrationEnabled() ? 1 : 0, security.getRegistrationTime(),
security.isInitialLoadEnabled() ? 1 : 0, security.getInitialLoadTime(), security.getNodeId() },
Expand Down Expand Up @@ -253,6 +277,19 @@ public Object mapRow(ResultSet rs, int num) throws SQLException {
}
}

class NodeSecurityResultSetExtractor implements ResultSetExtractor {
public Object extractData(ResultSet rs) throws SQLException, DataAccessException {
Map<String, NodeSecurity> result = new HashMap<String, NodeSecurity>();
NodeSecurityRowMapper mapper = new NodeSecurityRowMapper();

while (rs.next()) {
NodeSecurity nodeSecurity = (NodeSecurity) mapper.mapRow(rs, 0);
result.put(nodeSecurity.getNodeId(), nodeSecurity);
}
return result;
}
}

public boolean isExternalIdRegistered(String nodeGroupId, String externalId) {
return jdbcTemplate.queryForInt(getSql("isNodeRegisteredSql"), new Object[] { nodeGroupId, externalId }) > 0;
}
Expand Down
6 changes: 6 additions & 0 deletions symmetric/src/main/resources/sql/node-service-sql.xml
Expand Up @@ -48,6 +48,12 @@
node_id = ?
</value>
</entry>
<entry key="findAllNodeSecuritySql">
<value>
select node_id, node_password, registration_enabled, registration_time,
initial_load_enabled, initial_load_time from ${sync.table.prefix}_node_security
</value>
</entry>
<entry key="findNodeIdentitySql">
<value>
select c.node_id, c.node_group_id, c.external_id, c.sync_enabled, c.sync_url,
Expand Down
Expand Up @@ -100,4 +100,9 @@ public String generateNodeId(String nodeGroupId, String externalId) {
public String generatePassword() {
return null;
}

public void flushNodeAuthorizedCache() {
// TODO Auto-generated method stub

}
}

0 comments on commit 0513a3f

Please sign in to comment.