diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/io/DefaultOfflineClientListener.java b/symmetric/src/main/java/org/jumpmind/symmetric/io/DefaultOfflineClientListener.java index e469cdd24e..1acd011d14 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/io/DefaultOfflineClientListener.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/io/DefaultOfflineClientListener.java @@ -48,7 +48,12 @@ public void offline(Node remoteNode) { } public void syncDisabled(Node remoteNode) { - log.warn("SyncDisabledException"); + log.warn("SyncDisabled"); + nodeService.deleteIdentity(); + } + + public void registrationRequired(Node remoteNode) { + log.warn("RegistrationRequired"); nodeService.deleteIdentity(); } diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/io/IOfflineClientListener.java b/symmetric/src/main/java/org/jumpmind/symmetric/io/IOfflineClientListener.java index 44435f7ace..6bc6a99419 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/io/IOfflineClientListener.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/io/IOfflineClientListener.java @@ -44,10 +44,16 @@ public interface IOfflineClientListener extends IExtensionPoint { public void busy(Node remoteNode); /** - * Called when this node is rejected because synchronization is disabled on the remoteNode + * Called when this node is rejected because synchronization is disabled on the remote node. * * @param remoteNode */ public void syncDisabled(Node remoteNode); + /** + * Called when this node is rejected because the node has not been registered with the remote node. + * @param remoteNode + */ + public void registrationRequired(Node remoteNode); + } diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/AbstractOfflineDetectorService.java b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/AbstractOfflineDetectorService.java index 86666066fd..34bc448175 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/AbstractOfflineDetectorService.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/AbstractOfflineDetectorService.java @@ -28,6 +28,7 @@ import org.jumpmind.symmetric.io.IOfflineClientListener; import org.jumpmind.symmetric.model.Node; import org.jumpmind.symmetric.service.IOfflineDetectorService; +import org.jumpmind.symmetric.service.RegistrationRequiredException; import org.jumpmind.symmetric.transport.AuthenticationException; import org.jumpmind.symmetric.transport.ConnectionRejectedException; import org.jumpmind.symmetric.transport.SyncDisabledException; @@ -66,6 +67,8 @@ protected void fireOffline(Exception error, Node remoteNode) { listener.notAuthenticated(remoteNode); } else if (isSyncDisabled(error)) { listener.syncDisabled(remoteNode); + } else if (isRegistrationRequired(error)) { + listener.registrationRequired(remoteNode); } } } @@ -106,14 +109,26 @@ protected boolean isBusy(Exception ex) { } protected boolean isSyncDisabled(Exception ex) { - boolean offline = false; + boolean syncDisabled = false; if (ex != null) { Throwable cause = ExceptionUtils.getRootCause(ex); - offline = cause instanceof SyncDisabledException; - if (offline == false && ex instanceof SyncDisabledException) { - offline = true; + syncDisabled = cause instanceof SyncDisabledException; + if (syncDisabled == false && ex instanceof SyncDisabledException) { + syncDisabled = true; } } - return offline; + return syncDisabled; + } + + protected boolean isRegistrationRequired(Exception ex) { + boolean registrationRequired = false; + if (ex != null) { + Throwable cause = ExceptionUtils.getRootCause(ex); + registrationRequired = cause instanceof RegistrationRequiredException; + if (registrationRequired == false && ex instanceof RegistrationRequiredException) { + registrationRequired = true; + } + } + return registrationRequired; } } diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java index dbd236f478..1a50956d48 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java @@ -232,7 +232,7 @@ protected List loadDataAndReturnBatches(IIncomingTransport transp } catch (AuthenticationException ex) { log.warn("AuthenticationFailed"); } catch (SyncDisabledException ex) { - log.warn("SyncDisabledException"); + log.warn("SyncDisabled"); throw ex; } catch (Throwable e) { if (dataLoader != null && dataLoader.getContext().getBatchId() > 0 && batch == null) { diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/PullService.java b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/PullService.java index 4555d8f53d..ccb5fa09bb 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/PullService.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/PullService.java @@ -79,7 +79,7 @@ synchronized public boolean pullData() { log.warn("AuthenticationFailed"); fireOffline(ex, node); } catch (SyncDisabledException ex) { - log.warn("SyncDisabledException"); + log.warn("SyncDisabled"); fireOffline(ex, node); } catch (SocketException ex) { log.warn("Message", ex.getMessage()); diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/PushService.java b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/PushService.java index 30949c05bf..2de8e93d70 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/PushService.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/PushService.java @@ -36,6 +36,7 @@ import org.jumpmind.symmetric.service.INodeService; import org.jumpmind.symmetric.service.IPushService; import org.jumpmind.symmetric.service.LockActionConstants; +import org.jumpmind.symmetric.service.RegistrationRequiredException; import org.jumpmind.symmetric.transport.AuthenticationException; import org.jumpmind.symmetric.transport.ConnectionRejectedException; import org.jumpmind.symmetric.transport.IOutgoingWithResponseTransport; @@ -150,7 +151,10 @@ private PushStatus pushToNode(Node remote) { log.warn("AuthenticationFailed"); fireOffline(ex, remote); } catch (SyncDisabledException ex) { - log.warn("SyncDisabledException"); + log.warn("SyncDisabled"); + fireOffline(ex, remote); + } catch (RegistrationRequiredException ex) { + log.warn("RegistrationRequired"); fireOffline(ex, remote); } catch (Exception ex) { // just report the error because we want to push to other nodes diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/transport/http/HttpOutgoingTransport.java b/symmetric/src/main/java/org/jumpmind/symmetric/transport/http/HttpOutgoingTransport.java index 36c9bbdced..265e7cb240 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/transport/http/HttpOutgoingTransport.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/transport/http/HttpOutgoingTransport.java @@ -35,6 +35,7 @@ import org.jumpmind.symmetric.common.Constants; import org.jumpmind.symmetric.model.ChannelMap; import org.jumpmind.symmetric.service.IConfigurationService; +import org.jumpmind.symmetric.service.RegistrationRequiredException; import org.jumpmind.symmetric.transport.AuthenticationException; import org.jumpmind.symmetric.transport.ConnectionRejectedException; import org.jumpmind.symmetric.transport.IOutgoingWithResponseTransport; @@ -148,6 +149,8 @@ private void analyzeResponseCode(int code) throws IOException { throw new AuthenticationException(); } else if (WebConstants.SYNC_DISABLED == code) { throw new SyncDisabledException(); + } else if (WebConstants.REGISTRATION_REQUIRED == code) { + throw new RegistrationRequiredException(); } } diff --git a/symmetric/src/main/resources/symmetric-messages.properties b/symmetric/src/main/resources/symmetric-messages.properties index 0366316cfa..26bbd404f7 100644 --- a/symmetric/src/main/resources/symmetric-messages.properties +++ b/symmetric/src/main/resources/symmetric-messages.properties @@ -159,6 +159,7 @@ RegistrationNotAllowedNoInitialLoad=Registration is not allowed until this node RegistrationOpened=Opened Registration for %s RegistrationRedirecting=Redirecting %s to %s for registration. RegistrationRedirectsMissing=There are no registration redirect nodes configured. +RegistrationRequired=Registration is required before this operation can complete. RouterMissing=Could not find configured router '%s' for trigger with the id of %s. Defaulting the router RouterIllegalColumnMatchExpression=The provided column match expression was invalid: %s. The full expression is %s. RouterStats=Routing '%s' stat %s=%s @@ -197,7 +198,7 @@ SymmetricDSManualUpgradeNeeded=A manual upgrade of the node is required. Can no SymmetricEngineMissing=Could not find a reference to the SymmetricEngine from %s SymmetricEngineNotRegistered=Did not run job because the engine is not registered. SymmetricEngineNotStarted=The engine is not currently started. -SyncDisabledException=Synchronization is disabled in the root node. +SyncDisabled=Synchronization is disabled on the server node. TableDropped=Just dropped table %s_CONFIG TableDuplicating=Duplicating table %s into %s TableGeneratingEventsFailure=Not generating data/data events for table %s because a trigger or trigger hist is not created yet. diff --git a/symmetric/src/test/java/org/jumpmind/symmetric/test/SimpleIntegrationTest.java b/symmetric/src/test/java/org/jumpmind/symmetric/test/SimpleIntegrationTest.java index c4a29ecfe4..dbb6a960a8 100644 --- a/symmetric/src/test/java/org/jumpmind/symmetric/test/SimpleIntegrationTest.java +++ b/symmetric/src/test/java/org/jumpmind/symmetric/test/SimpleIntegrationTest.java @@ -1127,7 +1127,7 @@ public void testSyncDisabled() { } @Test - public void testClientNodeNotRegistered() { + public void testClientNodeNotRegistered() throws ParseException { logTestRunning(); Node clientIdentity = getClientEngine().getNodeService().findIdentity(); @@ -1142,9 +1142,18 @@ public void testClientNodeNotRegistered() { getRootEngine().getParameterService().saveParameter("auto.registration", true); getRootEngine().getParameterService().saveParameter("auto.reload", true); + + turnOnNoKeysInUpdateParameter(true); + Date date = DateUtils.parseDate("2007-01-03", new String[] { "yyyy-MM-dd" }); + clientJdbcTemplate.update(insertOrderHeaderSql, new Object[] { "99", 100, null, date }, new int[] { + Types.VARCHAR, Types.INTEGER, Types.CHAR, Types.DATE }); + clientJdbcTemplate.update(insertOrderDetailSql, new Object[] { "99", 1, "STK", "110000099", 3, 3.33 }); + getClientEngine().push(); + // A pull will cause the registration to occur and the node identify to be // reestablished. getClientEngine().pull(); + Node clientNodeAfterPull = getClientEngine().getNodeService().findIdentity(); Assert.assertNotNull(clientNodeAfterPull); }