Skip to content

Commit

Permalink
0000751: Add new extension point called INodeIdCreator that replaces …
Browse files Browse the repository at this point in the history
…INodeIdGenerator and gets the remote address and host passed to it
  • Loading branch information
chenson42 committed Aug 7, 2012
1 parent 5448f8c commit 5c0f3c8
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 75 deletions.
4 changes: 2 additions & 2 deletions symmetric-assemble/src/docbook/extensions.xml
Expand Up @@ -176,11 +176,11 @@
</para>
</section>
<section id="extensions-node-id-generator">
<title>INodeIdGenerator</title>
<title>INodeIdCreator</title>
<para>
This extension point allows SymmetricDS users to implement their own algorithms for how
node ids and passwords are generated or selected during the registration process. There may be
only one node generator per SymmetricDS instance.
only one node creator per SymmetricDS instance (Please note that the node creator extension has replaced the node generator extension).
</para>
</section>
<section id="extensions-trigger-creation-listener">
Expand Down
Expand Up @@ -28,9 +28,11 @@
import org.jumpmind.extension.IBuiltInExtensionPoint;
import org.jumpmind.extension.IExtensionPoint;
import org.jumpmind.symmetric.ISymmetricEngine;
import org.jumpmind.symmetric.config.INodeIdCreator;
import org.jumpmind.symmetric.config.INodeIdGenerator;
import org.jumpmind.symmetric.config.IParameterFilter;
import org.jumpmind.symmetric.config.ITriggerCreationListener;
import org.jumpmind.symmetric.config.NodeIdCreatorAdaptor;
import org.jumpmind.symmetric.io.IOfflineClientListener;
import org.jumpmind.symmetric.io.data.transform.IColumnTransform;
import org.jumpmind.symmetric.io.data.writer.IDatabaseWriterErrorHandler;
Expand Down Expand Up @@ -217,8 +219,16 @@ protected boolean registerExtension(String beanName, IExtensionPoint ext) {
installed = true;
extensionPoints.add(new ExtensionPointMetaData(ext, beanName, INodeIdGenerator.class,
true));
engine.getNodeService().setNodeIdGenerator((INodeIdGenerator) ext);
engine.getNodeService().setNodeIdCreator(
new NodeIdCreatorAdaptor((INodeIdGenerator) ext, engine.getNodeService()));
}

if (ext instanceof INodeIdCreator) {
installed = true;
extensionPoints.add(new ExtensionPointMetaData(ext, beanName, INodeIdCreator.class,
true));
engine.getNodeService().setNodeIdCreator((INodeIdCreator) ext);
}

if (ext instanceof IDataRouter) {
installed = true;
Expand Down
Expand Up @@ -35,7 +35,7 @@ public void testExportTableInSchemaOnH2() throws Exception {
export.setNoData(false);

String output = export.exportTables(new String[] {"TEST"}).toLowerCase();

System.out.println(output);
// TODO validate
}
}
Expand Down
@@ -0,0 +1,32 @@
package org.jumpmind.symmetric.config;

import org.jumpmind.extension.IExtensionPoint;
import org.jumpmind.symmetric.model.Node;
import org.jumpmind.symmetric.util.DefaultNodeIdCreator;

/**
* An {@link IExtensionPoint} that allows SymmetricDS users to implement their
* own algorithms for how node_ids and passwords are generated or selected
* during registration. There may be only one node creator per SymmetricDS instance.
* </p>
* The default implementation of this is the {@link DefaultNodeIdCreator}
*/
public interface INodeIdCreator extends IExtensionPoint {

/**
* Based on the node parameters passed in generate an expected node id. This
* is used in an attempt to match a registration request with an open registration.
*/
public String selectNodeId(Node node, String remoteHost, String remoteAddress);

/**
* Based on the node parameters passed in generate a brand new node id.
*/
public String generateNodeId(Node node, String remoteHost, String remoteAddress);

/**
* Generate a password to use when opening registration
*/
public String generatePassword(Node node);

}
Expand Up @@ -23,15 +23,16 @@
import org.jumpmind.extension.IExtensionPoint;
import org.jumpmind.symmetric.model.Node;
import org.jumpmind.symmetric.service.INodeService;
import org.jumpmind.symmetric.util.DefaultNodeIdGenerator;
import org.jumpmind.symmetric.util.DefaultNodeIdCreator;

/**
* An {@link IExtensionPoint} that allows SymmetricDS users to implement their
* own algorithms for how node_ids and passwords are generated or selected
* during registration. There may be only one node generator per SymmetricDS instance.
* </p>
* The default implementation of this is the {@link DefaultNodeIdGenerator}
* The default implementation of this is the {@link DefaultNodeIdCreator}
*/
@Deprecated
public interface INodeIdGenerator extends IExtensionPoint {

/**
Expand Down
@@ -0,0 +1,28 @@
package org.jumpmind.symmetric.config;

import org.jumpmind.symmetric.model.Node;
import org.jumpmind.symmetric.service.INodeService;

public class NodeIdCreatorAdaptor implements INodeIdCreator {

private INodeService nodeService;
private INodeIdGenerator nodeIdGenerator;

public NodeIdCreatorAdaptor(INodeIdGenerator generator, INodeService nodeService) {
this.nodeIdGenerator = generator;
this.nodeService = nodeService;
}

public String selectNodeId(Node node, String remoteHost, String remoteAddress) {
return nodeIdGenerator.selectNodeId(nodeService, node);
}

public String generateNodeId(Node node, String remoteHost, String remoteAddress) {
return nodeIdGenerator.generateNodeId(nodeService, node);
}

public String generatePassword(Node node) {
return nodeIdGenerator.generatePassword(nodeService, node);
}

}
Expand Up @@ -27,7 +27,7 @@
import java.util.Set;

import org.jumpmind.db.sql.ISqlTransaction;
import org.jumpmind.symmetric.config.INodeIdGenerator;
import org.jumpmind.symmetric.config.INodeIdCreator;
import org.jumpmind.symmetric.ext.IOfflineServerListener;
import org.jumpmind.symmetric.io.IOfflineClientListener;
import org.jumpmind.symmetric.model.NetworkedNode;
Expand Down Expand Up @@ -126,9 +126,9 @@ public void ignoreNodeChannelForExternalId(boolean ignore, String channelId,

public boolean setInitialLoadEnabled(ISqlTransaction transaction, String nodeId, boolean initialLoadEnabled);

public INodeIdGenerator getNodeIdGenerator();
public INodeIdCreator getNodeIdCreator();

public void setNodeIdGenerator(INodeIdGenerator nodeIdGenerator);
public void setNodeIdCreator(INodeIdCreator nodeIdGenerator);

public void setNodePasswordFilter(INodePasswordFilter nodePasswordFilter);

Expand Down
Expand Up @@ -39,7 +39,7 @@
import org.jumpmind.db.sql.UniqueKeyException;
import org.jumpmind.db.sql.mapper.StringMapper;
import org.jumpmind.symmetric.common.ParameterConstants;
import org.jumpmind.symmetric.config.INodeIdGenerator;
import org.jumpmind.symmetric.config.INodeIdCreator;
import org.jumpmind.symmetric.db.ISymmetricDialect;
import org.jumpmind.symmetric.ext.IOfflineServerListener;
import org.jumpmind.symmetric.model.NetworkedNode;
Expand All @@ -52,7 +52,7 @@
import org.jumpmind.symmetric.service.INodeService;
import org.jumpmind.symmetric.service.IParameterService;
import org.jumpmind.symmetric.util.AppUtils;
import org.jumpmind.symmetric.util.DefaultNodeIdGenerator;
import org.jumpmind.symmetric.util.DefaultNodeIdCreator;

/**
* @see INodeService
Expand All @@ -65,7 +65,7 @@ public class NodeService extends AbstractService implements INodeService {

private long securityCacheTime;

private INodeIdGenerator nodeIdGenerator;
private INodeIdCreator nodeIdCreator;

private INodePasswordFilter nodePasswordFilter;

Expand All @@ -75,7 +75,7 @@ public class NodeService extends AbstractService implements INodeService {

public NodeService(IParameterService parameterService, ISymmetricDialect dialect) {
super(parameterService, dialect);
nodeIdGenerator = new DefaultNodeIdGenerator(parameterService);
nodeIdCreator = new DefaultNodeIdCreator(parameterService, this);
setSqlMap(new NodeServiceSqlMap(symmetricDialect.getPlatform(),
createSqlReplacementTokens()));
}
Expand Down Expand Up @@ -225,7 +225,7 @@ public void deleteNode(String nodeId) {

public void insertNodeSecurity(String id) {
flushNodeAuthorizedCache();
String password = nodeIdGenerator.generatePassword(this, new Node(id, null, null));
String password = nodeIdCreator.generatePassword(new Node(id, null, null));
password = filterPasswordOnSaveIfNeeded(password);
sqlTemplate.update(getSql("insertNodeSecuritySql"), new Object[] { id, password,
findIdentity().getNodeId() });
Expand Down Expand Up @@ -453,12 +453,12 @@ public boolean isExternalIdRegistered(String nodeGroupId, String externalId) {
externalId }) > 0;
}

public INodeIdGenerator getNodeIdGenerator() {
return nodeIdGenerator;
public INodeIdCreator getNodeIdCreator() {
return nodeIdCreator;
}

public void setNodeIdGenerator(INodeIdGenerator nodeIdGenerator) {
this.nodeIdGenerator = nodeIdGenerator;
public void setNodeIdCreator(INodeIdCreator nodeIdGenerator) {
this.nodeIdCreator = nodeIdGenerator;
}

public boolean isDataLoadCompleted() {
Expand Down
Expand Up @@ -126,15 +126,15 @@ public boolean registerNode(Node preRegisteredNode, String remoteHost, String re
throw new RegistrationRedirectException(redirectUrl);
}

String nodeId = StringUtils.isBlank(preRegisteredNode.getNodeId()) ? nodeService.getNodeIdGenerator()
.selectNodeId(nodeService, preRegisteredNode) : preRegisteredNode.getNodeId();
String nodeId = StringUtils.isBlank(preRegisteredNode.getNodeId()) ? nodeService.getNodeIdCreator()
.selectNodeId(preRegisteredNode, remoteHost, remoteAddress) : preRegisteredNode.getNodeId();
Node registeredNode = nodeService.findNode(nodeId);
NodeSecurity security = nodeService.findNodeSecurity(nodeId);
if ((registeredNode == null || security == null || !security.isRegistrationEnabled())
&& parameterService.is(ParameterConstants.AUTO_REGISTER_ENABLED)) {
openRegistration(preRegisteredNode);
nodeId = StringUtils.isBlank(preRegisteredNode.getNodeId()) ? nodeService.getNodeIdGenerator()
.selectNodeId(nodeService, preRegisteredNode) : preRegisteredNode.getNodeId();
nodeId = StringUtils.isBlank(preRegisteredNode.getNodeId()) ? nodeService.getNodeIdCreator()
.selectNodeId(preRegisteredNode, remoteHost, remoteAddress) : preRegisteredNode.getNodeId();
security = nodeService.findNodeSecurity(nodeId);
registeredNode = nodeService.findNode(nodeId);
} else if (registeredNode == null || security == null || !security.isRegistrationEnabled()) {
Expand Down Expand Up @@ -330,7 +330,7 @@ protected void sendInitialLoadFromRegisteredNode() {
*/
public synchronized void reOpenRegistration(String nodeId) {
Node node = nodeService.findNode(nodeId);
String password = nodeService.getNodeIdGenerator().generatePassword(nodeService, node);
String password = nodeService.getNodeIdCreator().generatePassword(node);
password = filterPasswordOnSaveIfNeeded(password);
if (node != null) {
int updateCount = sqlTemplate.update(getSql("reopenRegistrationSql"), new Object[] {
Expand Down Expand Up @@ -368,7 +368,7 @@ public synchronized String openRegistration(Node node) {
if (me != null
|| (parameterService.getExternalId().equals(node.getExternalId()) && parameterService
.getNodeGroupId().equals(node.getNodeGroupId()))) {
String nodeId = nodeService.getNodeIdGenerator().generateNodeId(nodeService, node);
String nodeId = nodeService.getNodeIdCreator().generateNodeId(node, null, null);
Node existingNode = nodeService.findNode(nodeId);
if (existingNode == null) {
node.setNodeId(nodeId);
Expand All @@ -379,8 +379,7 @@ public synchronized String openRegistration(Node node) {
// make sure there isn't a node security row lying around w/out
// a node row
nodeService.deleteNodeSecurity(nodeId);
String password = nodeService.getNodeIdGenerator().generatePassword(nodeService,
node);
String password = nodeService.getNodeIdCreator().generatePassword(node);
password = filterPasswordOnSaveIfNeeded(password);
sqlTemplate.update(getSql("openRegistrationNodeSecuritySql"), new Object[] {
nodeId, password, me.getNodeId() });
Expand Down
Expand Up @@ -21,11 +21,9 @@

package org.jumpmind.symmetric.util;

import java.net.URL;

import org.apache.commons.lang.StringUtils;
import org.jumpmind.symmetric.common.ParameterConstants;
import org.jumpmind.symmetric.config.INodeIdGenerator;
import org.jumpmind.symmetric.config.INodeIdCreator;
import org.jumpmind.symmetric.model.Node;
import org.jumpmind.symmetric.model.NodeSecurity;
import org.jumpmind.symmetric.service.INodeService;
Expand All @@ -37,20 +35,23 @@
import bsh.EvalError;
import bsh.Interpreter;

public class DefaultNodeIdGenerator implements INodeIdGenerator {
public class DefaultNodeIdCreator implements INodeIdCreator {

protected final Logger log = LoggerFactory.getLogger(getClass());

protected IParameterService parameterService;

protected INodeService nodeService;

public DefaultNodeIdGenerator(IParameterService parameterService) {
public DefaultNodeIdCreator(IParameterService parameterService, INodeService nodeService) {
this.parameterService = parameterService;
}

public String selectNodeId(INodeService nodeService, Node node) {
this.nodeService = nodeService;
}

public String selectNodeId(Node node, String remoteHost, String remoteAddress) {
final int maxTries = parameterService.getInt(ParameterConstants.NODE_ID_GENERATOR_MAX_NODES, 100);
if (StringUtils.isBlank(node.getNodeId())) {
String nodeId = evaluateScript(node);
String nodeId = evaluateScript(node, remoteHost, remoteAddress);
if (StringUtils.isBlank(nodeId)) {
nodeId = buildNodeId(nodeService, node);
for (int sequence = 0; sequence < maxTries; sequence++) {
Expand All @@ -67,11 +68,11 @@ public String selectNodeId(INodeService nodeService, Node node) {
return node.getNodeId();
}

public String generateNodeId(INodeService nodeService, Node node) {
public String generateNodeId(Node node, String remoteHost, String remoteAddress) {
final int maxTries = parameterService.getInt(ParameterConstants.NODE_ID_GENERATOR_MAX_NODES, 100);
String nodeId = node.getNodeId();
if (StringUtils.isBlank(nodeId)) {
nodeId = evaluateScript(node);
nodeId = evaluateScript(node, remoteHost, remoteAddress);
if (StringUtils.isBlank(nodeId)) {
nodeId = buildNodeId(nodeService, node);
for (int sequence = 0; sequence < maxTries; sequence++) {
Expand All @@ -98,23 +99,20 @@ public String generateNodeId(INodeService nodeService, Node node) {
protected String buildNodeId(INodeService nodeService, Node node) {
return StringUtils.isBlank(node.getExternalId()) ? "0" : node.getExternalId();
}

public String generatePassword(INodeService nodeService, Node node) {
public String generatePassword(Node node) {
return new SecurityService().nextSecureHexString(30);
}

protected String evaluateScript(Node node) {
protected String evaluateScript(Node node, String remoteHost, String remoteAddress) {
String script = parameterService.getString(ParameterConstants.NODE_ID_GENERATOR_SCRIPT);
if (StringUtils.isNotBlank(script)) {
try {
Interpreter interpreter = new Interpreter();
interpreter.set("node", node);
try {
URL url = new URL(node.getSyncUrl());
interpreter.set("hostname", url.getHost());
} catch (Exception ex) {
interpreter.set("hostname", null);
}
interpreter.set("hostname", remoteHost);
interpreter.set("remoteHost", remoteHost);
interpreter.set("remoteAddress", remoteAddress);
Object retValue = interpreter.eval(script);
if (retValue != null) {
return retValue.toString();
Expand Down
Expand Up @@ -27,7 +27,7 @@
import java.util.Set;

import org.jumpmind.db.sql.ISqlTransaction;
import org.jumpmind.symmetric.config.INodeIdGenerator;
import org.jumpmind.symmetric.config.INodeIdCreator;
import org.jumpmind.symmetric.ext.IOfflineServerListener;
import org.jumpmind.symmetric.model.NetworkedNode;
import org.jumpmind.symmetric.model.Node;
Expand Down Expand Up @@ -195,11 +195,11 @@ public String generatePassword() {
public void flushNodeAuthorizedCache() {
}

public INodeIdGenerator getNodeIdGenerator() {
public INodeIdCreator getNodeIdCreator() {
return null;
}

public void setNodeIdGenerator(INodeIdGenerator nodeIdGenerator) {
public void setNodeIdCreator(INodeIdCreator nodeIdGenerator) {
}

public boolean isDataLoadCompleted() {
Expand Down

0 comments on commit 5c0f3c8

Please sign in to comment.