Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2010-09-22 08:06:37 +0000
committerEike Stepper2010-09-22 08:06:37 +0000
commit4b6e0c127bf8fff569460c78c13273a7c4056539 (patch)
tree89c28dd6cbc6290c016f9880b1b8980893474e1e
parent869595029453fc374329e764522f25b3925c9f1e (diff)
downloadcdo-4b6e0c127bf8fff569460c78c13273a7c4056539.tar.gz
cdo-4b6e0c127bf8fff569460c78c13273a7c4056539.tar.xz
cdo-4b6e0c127bf8fff569460c78c13273a7c4056539.zip
[325928] Provide FailoverMonitor server and FailoverAgents to coordinate fail-over scenarios
https://bugs.eclipse.org/bugs/show_bug.cgi?id=325928
-rw-r--r--plugins/org.eclipse.emf.cdo.examples/src/org/eclipse/emf/cdo/examples/server/FailOverExample.java317
-rw-r--r--plugins/org.eclipse.emf.cdo.examples/src/org/eclipse/emf/cdo/examples/server/FailoverExample.java538
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/syncing/FailoverAgent.java286
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/syncing/FailoverMonitor.java271
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/net4j/CDONet4jServerUtil.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/FailoverParticipant.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java17
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalFailoverParticipant.java22
-rw-r--r--plugins/org.eclipse.net4j/META-INF/MANIFEST.MF30
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/net4j/Net4jUtil.java4
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/heartbeat/HeartBeatProtocol.java47
12 files changed, 1197 insertions, 342 deletions
diff --git a/plugins/org.eclipse.emf.cdo.examples/src/org/eclipse/emf/cdo/examples/server/FailOverExample.java b/plugins/org.eclipse.emf.cdo.examples/src/org/eclipse/emf/cdo/examples/server/FailOverExample.java
deleted file mode 100644
index db423383e4..0000000000
--- a/plugins/org.eclipse.emf.cdo.examples/src/org/eclipse/emf/cdo/examples/server/FailOverExample.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/**
- * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.examples.server;
-
-import org.eclipse.emf.cdo.common.CDOCommonRepository.Type;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
-import org.eclipse.emf.cdo.net4j.CDONet4jUtil;
-import org.eclipse.emf.cdo.net4j.CDOSessionConfiguration;
-import org.eclipse.emf.cdo.server.CDOServerUtil;
-import org.eclipse.emf.cdo.server.IRepository;
-import org.eclipse.emf.cdo.server.IRepositorySynchronizer;
-import org.eclipse.emf.cdo.server.IStore;
-import org.eclipse.emf.cdo.server.db.CDODBUtil;
-import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-import org.eclipse.emf.cdo.server.net4j.CDONet4jServerUtil;
-import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-
-import org.eclipse.net4j.Net4jUtil;
-import org.eclipse.net4j.acceptor.IAcceptor;
-import org.eclipse.net4j.connector.IConnector;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.db.IDBConnectionProvider;
-import org.eclipse.net4j.db.h2.H2Adapter;
-import org.eclipse.net4j.tcp.TCPUtil;
-import org.eclipse.net4j.util.container.ContainerUtil;
-import org.eclipse.net4j.util.container.IManagedContainer;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.OMPlatform;
-import org.eclipse.net4j.util.om.log.PrintLogHandler;
-import org.eclipse.net4j.util.om.trace.PrintTraceHandler;
-
-import org.h2.jdbcx.JdbcDataSource;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- * @since 4.0
- */
-public abstract class FailOverExample
-{
- public static final String TRANSPORT_TYPE = "tcp";
-
- protected int port;
-
- protected String name;
-
- protected boolean master;
-
- protected String peerHost;
-
- protected int peerPort;
-
- protected String peerRepository;
-
- protected transient IManagedContainer container;
-
- protected transient IRepository repository;
-
- protected transient IAcceptor acceptor;
-
- public FailOverExample(int port, String name, boolean master, String peerHost, int peerPort, String peerRepository)
- {
- this.port = port;
- this.name = name;
- this.master = master;
- this.peerHost = peerHost;
- this.peerPort = peerPort;
- this.peerRepository = peerRepository;
-
- enableLoggingAndTracing();
- container = createContainer();
- }
-
- public void init()
- {
- IStore store = createStore();
- Map<String, String> props = createProperties();
- IRepositorySynchronizer synchronizer = createRepositorySynchronizer();
-
- repository = CDOServerUtil.createFailoverParticipant(name, store, props, synchronizer, master);
- CDOServerUtil.addRepository(container, repository);
-
- connect();
- }
-
- public void run() throws Exception
- {
- for (;;)
- {
- System.out.println();
- System.out.println("Enter a command:");
- System.out.println("0 - exit");
- System.out.println("1 - connect repository to network");
- System.out.println("2 - disconnect repository from network");
- System.out.println("3 - dump repository infos");
- System.out.println("4 - set repository type MASTER");
- System.out.println("5 - set repository type BACKUP");
- System.out.print("root@" + name + ":~> ");
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- String command = reader.readLine();
-
- if ("1".equals(command))
- {
- if (acceptor == null)
- {
- connect();
- }
- else
- {
- System.out.println("Already connected");
- }
- }
- else if ("2".equals(command))
- {
- if (acceptor != null)
- {
- disconnect();
- }
- else
- {
- System.out.println("Already disconnected");
- }
- }
- else if ("3".equals(command))
- {
- System.out.println();
- System.out.println(repository.getName() + ": " + repository.getType()
- + (repository.getType() == Type.BACKUP ? "|" + repository.getState() : ""));
- }
- else if ("4".equals(command))
- {
- if (repository.getType() == Type.BACKUP)
- {
- System.out.println("Setting repository type MASTER...");
- ((InternalRepository)repository).setType(Type.MASTER);
- System.out.println("Type is " + repository.getType());
- }
- else
- {
- System.out.println("Already MASTER");
- }
- }
- else if ("5".equals(command))
- {
- if (repository.getType() == Type.MASTER)
- {
- System.out.println("Setting repository type BACKUP...");
- ((InternalRepository)repository).setType(Type.BACKUP);
- System.out.println("Type is " + repository.getType());
- }
- else
- {
- System.out.println("Already BACKUP");
- }
- }
- else if ("0".equals(command))
- {
- System.out.println("Exiting...");
- break;
- }
- else
- {
- System.out.println("Unknown command");
- }
- }
- }
-
- public void done()
- {
- LifecycleUtil.deactivate(acceptor);
- LifecycleUtil.deactivate(repository);
- container.deactivate();
- }
-
- protected void connect()
- {
- System.out.println("Connecting to network...");
- acceptor = createAcceptor();
- System.out.println("Connected");
- }
-
- protected void disconnect()
- {
- System.out.println("Disconnecting from network...");
- LifecycleUtil.deactivate(acceptor);
- acceptor = null;
- System.out.println("Disconnected");
- }
-
- protected void enableLoggingAndTracing()
- {
- OMPlatform.INSTANCE.setDebugging(true);
- OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
- OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOLE);
- }
-
- protected IManagedContainer createContainer()
- {
- IManagedContainer container = ContainerUtil.createContainer();
- Net4jUtil.prepareContainer(container); // Register Net4j factories
- TCPUtil.prepareContainer(container); // Register TCP factories
- CDONet4jUtil.prepareContainer(container); // Register CDO client factories
- CDONet4jServerUtil.prepareContainer(container); // Register CDO server factories
- container.activate();
- return container;
- }
-
- protected IStore createStore()
- {
- JdbcDataSource dataSource = new JdbcDataSource();
- dataSource.setURL("jdbc:h2:_database/" + name);
-
- IMappingStrategy mappingStrategy = CDODBUtil.createHorizontalMappingStrategy(true, true);
- IDBAdapter dbAdapter = new H2Adapter();
- IDBConnectionProvider dbConnectionProvider = DBUtil.createConnectionProvider(dataSource);
- return CDODBUtil.createStore(mappingStrategy, dbAdapter, dbConnectionProvider);
- }
-
- protected Map<String, String> createProperties()
- {
- Map<String, String> props = new HashMap<String, String>();
- props.put(IRepository.Props.OVERRIDE_UUID, name);
- props.put(IRepository.Props.SUPPORTING_AUDITS, "true");
- props.put(IRepository.Props.SUPPORTING_BRANCHES, "true");
- return props;
- }
-
- protected IRepositorySynchronizer createRepositorySynchronizer()
- {
- CDOSessionConfigurationFactory factory = new CDOSessionConfigurationFactory()
- {
- public CDOSessionConfiguration createSessionConfiguration()
- {
- IConnector connector = createConnector();
-
- CDOSessionConfiguration configuration = CDONet4jUtil.createSessionConfiguration();
- configuration.setConnector(connector);
- configuration.setRepositoryName(peerRepository);
- configuration.setRevisionManager(CDORevisionUtil.createRevisionManager(CDORevisionCache.NOOP));
- return configuration;
- }
- };
-
- IRepositorySynchronizer synchronizer = CDOServerUtil.createRepositorySynchronizer(factory);
- synchronizer.setRetryInterval(2);
- synchronizer.setRawReplication(true);
- synchronizer.setMaxRecommits(10);
- synchronizer.setRecommitInterval(2);
- return synchronizer;
- }
-
- protected IAcceptor createAcceptor()
- {
- return (IAcceptor)container.getElement("org.eclipse.net4j.acceptors", TRANSPORT_TYPE, "0.0.0.0:" + port);
- }
-
- protected IConnector createConnector()
- {
- String description = peerHost + ":" + peerPort;
- container.removeElement("org.eclipse.net4j.connectors", TRANSPORT_TYPE, description);
- return (IConnector)container.getElement("org.eclipse.net4j.connectors", TRANSPORT_TYPE, description);
- }
-
- /**
- * @author Eike Stepper
- */
- public static final class InitialMaster extends FailOverExample
- {
- public InitialMaster()
- {
- super(2036, "repo1", true, "localhost", 2037, "repo2");
- }
-
- public static void main(String[] args) throws Exception
- {
- FailOverExample example = new InitialMaster();
- example.init();
- example.run();
- example.done();
- }
- }
-
- /**
- * @author Eike Stepper
- */
- public static final class InitialBackup extends FailOverExample
- {
- public InitialBackup()
- {
- super(2037, "repo2", false, "localhost", 2036, "repo1");
- }
-
- public static void main(String[] args) throws Exception
- {
- FailOverExample example = new InitialBackup();
- example.init();
- example.run();
- example.done();
- }
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.examples/src/org/eclipse/emf/cdo/examples/server/FailoverExample.java b/plugins/org.eclipse.emf.cdo.examples/src/org/eclipse/emf/cdo/examples/server/FailoverExample.java
new file mode 100644
index 0000000000..acc933ce81
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.examples/src/org/eclipse/emf/cdo/examples/server/FailoverExample.java
@@ -0,0 +1,538 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.examples.server;
+
+import org.eclipse.emf.cdo.common.CDOCommonRepository.Type;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
+import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
+import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
+import org.eclipse.emf.cdo.net4j.CDONet4jUtil;
+import org.eclipse.emf.cdo.net4j.CDOSessionConfiguration;
+import org.eclipse.emf.cdo.server.CDOServerUtil;
+import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.server.IRepositorySynchronizer;
+import org.eclipse.emf.cdo.server.IStore;
+import org.eclipse.emf.cdo.server.ISynchronizableRepository;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.net4j.syncing.FailoverAgent;
+import org.eclipse.emf.cdo.server.internal.net4j.syncing.FailoverMonitor;
+import org.eclipse.emf.cdo.server.internal.net4j.syncing.FailoverMonitor.Protocol;
+import org.eclipse.emf.cdo.server.net4j.CDONet4jServerUtil;
+import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+
+import org.eclipse.net4j.Net4jUtil;
+import org.eclipse.net4j.acceptor.IAcceptor;
+import org.eclipse.net4j.connector.IConnector;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.IDBAdapter;
+import org.eclipse.net4j.db.IDBConnectionProvider;
+import org.eclipse.net4j.db.h2.H2Adapter;
+import org.eclipse.net4j.tcp.TCPUtil;
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.container.ContainerEventAdapter;
+import org.eclipse.net4j.util.container.ContainerUtil;
+import org.eclipse.net4j.util.container.IContainer;
+import org.eclipse.net4j.util.container.IManagedContainer;
+import org.eclipse.net4j.util.event.IEvent;
+import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+
+import org.h2.jdbcx.JdbcDataSource;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public abstract class FailoverExample
+{
+ public static final String TRANSPORT_TYPE = "tcp";
+
+ protected int port;
+
+ protected String name;
+
+ protected transient IManagedContainer container;
+
+ protected transient IRepository repository;
+
+ protected transient IAcceptor acceptor;
+
+ static
+ {
+ // OMPlatform.INSTANCE.setDebugging(true);
+ // OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
+ // OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOLE);
+ }
+
+ public FailoverExample()
+ {
+ container = createContainer();
+ }
+
+ public static IManagedContainer createContainer()
+ {
+ IManagedContainer container = ContainerUtil.createContainer();
+ ContainerUtil.prepareContainer(container); // Register general stuff
+ Net4jUtil.prepareContainer(container); // Register Net4j factories
+ TCPUtil.prepareContainer(container); // Register TCP factories
+ CDONet4jUtil.prepareContainer(container); // Register CDO client factories
+ CDONet4jServerUtil.prepareContainer(container); // Register CDO server factories
+ container.activate();
+ return container;
+ }
+
+ public void init()
+ {
+ IStore store = createStore();
+ Map<String, String> props = createProperties();
+
+ repository = createRepository(store, props);
+ CDOServerUtil.addRepository(container, repository);
+
+ repository.addListener(new IListener()
+ {
+ public void notifyEvent(IEvent event)
+ {
+ if (event instanceof RepositoryTypeChangedEvent)
+ {
+ RepositoryTypeChangedEvent e = (RepositoryTypeChangedEvent)event;
+ System.out.println("Type changed to " + e.getNewType());
+ }
+ else if (event instanceof RepositoryStateChangedEvent)
+ {
+ RepositoryStateChangedEvent e = (RepositoryStateChangedEvent)event;
+ System.out.println("State changed to " + e.getNewState());
+ }
+ }
+ });
+
+ connect();
+ }
+
+ public void run() throws Exception
+ {
+ for (;;)
+ {
+ System.out.println();
+ System.out.println("Enter a command:");
+ showMenu();
+ System.out.println();
+
+ String command = new BufferedReader(new InputStreamReader(System.in)).readLine();
+ if (handleCommand(command))
+ {
+ break;
+ }
+ }
+ }
+
+ public void done()
+ {
+ LifecycleUtil.deactivate(acceptor);
+ LifecycleUtil.deactivate(repository);
+ container.deactivate();
+ }
+
+ protected void showMenu()
+ {
+ System.out.println("0 - exit");
+ System.out.println("1 - connect repository to network");
+ System.out.println("2 - disconnect repository from network");
+ System.out.println("3 - dump repository infos");
+ }
+
+ protected boolean handleCommand(String command)
+ {
+ if ("1".equals(command))
+ {
+ if (acceptor == null)
+ {
+ connect();
+ }
+ else
+ {
+ System.out.println("Already connected");
+ }
+ }
+ else if ("2".equals(command))
+ {
+ if (acceptor != null)
+ {
+ disconnect();
+ }
+ else
+ {
+ System.out.println("Already disconnected");
+ }
+ }
+ else if ("3".equals(command))
+ {
+ System.out.println();
+ System.out.println(repository.getName() + ": " + repository.getType()
+ + (repository.getType() == Type.BACKUP ? "|" + repository.getState() : ""));
+ }
+ else if ("0".equals(command))
+ {
+ System.out.println("Exiting...");
+ return true;
+ }
+ else
+ {
+ System.out.println("Unknown command");
+ }
+
+ return false;
+ }
+
+ protected void connect()
+ {
+ System.out.println("Connecting to network...");
+ acceptor = createAcceptor();
+ System.out.println("Connected");
+ }
+
+ protected void disconnect()
+ {
+ System.out.println("Disconnecting from network...");
+ LifecycleUtil.deactivate(acceptor);
+ acceptor = null;
+ System.out.println("Disconnected");
+ }
+
+ protected IStore createStore()
+ {
+ JdbcDataSource dataSource = new JdbcDataSource();
+ dataSource.setURL("jdbc:h2:_database/" + name);
+
+ IMappingStrategy mappingStrategy = CDODBUtil.createHorizontalMappingStrategy(true, true);
+ IDBAdapter dbAdapter = new H2Adapter();
+ IDBConnectionProvider dbConnectionProvider = DBUtil.createConnectionProvider(dataSource);
+ return CDODBUtil.createStore(mappingStrategy, dbAdapter, dbConnectionProvider);
+ }
+
+ protected Map<String, String> createProperties()
+ {
+ Map<String, String> props = new HashMap<String, String>();
+ props.put(IRepository.Props.OVERRIDE_UUID, name);
+ props.put(IRepository.Props.SUPPORTING_AUDITS, "true");
+ props.put(IRepository.Props.SUPPORTING_BRANCHES, "true");
+ return props;
+ }
+
+ protected abstract IRepository createRepository(IStore store, Map<String, String> props);
+
+ protected IAcceptor createAcceptor()
+ {
+ return (IAcceptor)container.getElement("org.eclipse.net4j.acceptors", TRANSPORT_TYPE, "0.0.0.0:" + port);
+ }
+
+ protected IConnector createConnector(String description)
+ {
+ container.removeElement("org.eclipse.net4j.connectors", TRANSPORT_TYPE, description);
+ return (IConnector)container.getElement("org.eclipse.net4j.connectors", TRANSPORT_TYPE, description);
+ }
+
+ protected IRepositorySynchronizer createRepositorySynchronizer(IConnector connector, String repositoryName)
+ {
+ CDOSessionConfigurationFactory factory = createSessionConfigurationFactory(connector, repositoryName);
+
+ IRepositorySynchronizer synchronizer = CDOServerUtil.createRepositorySynchronizer(factory);
+ synchronizer.setRetryInterval(2);
+ synchronizer.setRawReplication(true);
+ synchronizer.setMaxRecommits(10);
+ synchronizer.setRecommitInterval(2);
+ return synchronizer;
+ }
+
+ protected CDOSessionConfigurationFactory createSessionConfigurationFactory(final IConnector connector,
+ final String repositoryName)
+ {
+ return new CDOSessionConfigurationFactory()
+ {
+ public CDOSessionConfiguration createSessionConfiguration()
+ {
+ return FailoverExample.this.createSessionConfiguration(connector, repositoryName);
+ }
+ };
+ }
+
+ protected CDOSessionConfiguration createSessionConfiguration(IConnector connector, String repositoryName)
+ {
+ CDOSessionConfiguration configuration = CDONet4jUtil.createSessionConfiguration();
+ configuration.setConnector(connector);
+ configuration.setRepositoryName(repositoryName);
+ configuration.setRevisionManager(CDORevisionUtil.createRevisionManager(CDORevisionCache.NOOP));
+ return configuration;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Unmonitored extends FailoverExample
+ {
+ protected boolean master;
+
+ protected String peerHost;
+
+ protected int peerPort;
+
+ protected String peerRepository;
+
+ public Unmonitored(int port, String name, boolean master, String peerHost, int peerPort, String peerRepository)
+ {
+ this.port = port;
+ this.name = name;
+ this.master = master;
+ this.peerHost = peerHost;
+ this.peerPort = peerPort;
+ this.peerRepository = peerRepository;
+ }
+
+ @Override
+ protected IRepository createRepository(IStore store, Map<String, String> props)
+ {
+ IConnector connector = createConnector(peerHost + ":" + peerPort);
+ IRepositorySynchronizer synchronizer = createRepositorySynchronizer(connector, peerRepository);
+ return CDOServerUtil.createFailoverParticipant(name, store, props, synchronizer, master);
+ }
+
+ @Override
+ protected void showMenu()
+ {
+ super.showMenu();
+ System.out.println("4 - set repository type MASTER");
+ System.out.println("5 - set repository type BACKUP");
+ }
+
+ @Override
+ protected boolean handleCommand(String command)
+ {
+ if ("4".equals(command))
+ {
+ if (repository.getType() == Type.BACKUP)
+ {
+ System.out.println("Setting repository type MASTER...");
+ ((InternalRepository)repository).setType(Type.MASTER);
+ System.out.println("Type is " + repository.getType());
+ }
+ else
+ {
+ System.out.println("Already MASTER");
+ }
+ }
+ else if ("5".equals(command))
+ {
+ if (repository.getType() == Type.MASTER)
+ {
+ System.out.println("Setting repository type BACKUP...");
+ ((InternalRepository)repository).setType(Type.BACKUP);
+ System.out.println("Type is " + repository.getType());
+ }
+ else
+ {
+ System.out.println("Already BACKUP");
+ }
+ }
+ else
+ {
+ return super.handleCommand(command);
+ }
+
+ return false;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class InitialMaster extends Unmonitored
+ {
+ public InitialMaster()
+ {
+ super(2036, "repo1", true, "localhost", 2037, "repo2");
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ FailoverExample example = new InitialMaster();
+ example.init();
+ example.run();
+ example.done();
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class InitialBackup extends Unmonitored
+ {
+ public InitialBackup()
+ {
+ super(2037, "repo2", false, "localhost", 2036, "repo1");
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ FailoverExample example = new InitialBackup();
+ example.init();
+ example.run();
+ example.done();
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Monitored extends FailoverExample
+ {
+ public static final String REPOSITORY_MONITOR_GROUP = "ExampleGroup";
+
+ protected String host;
+
+ public Monitored(String host, int port, String name)
+ {
+ this.host = host;
+ this.port = port;
+ this.name = name;
+ }
+
+ @Override
+ protected IRepository createRepository(IStore store, Map<String, String> props)
+ {
+ ISynchronizableRepository repository = CDOServerUtil.createFailoverParticipant(name, store, props);
+
+ FailoverAgent agent = new FailoverAgent()
+ {
+ @Override
+ protected org.eclipse.emf.cdo.session.CDOSessionConfiguration createSessionConfiguration(
+ String connectorDescription, String repositoryName)
+ {
+ IConnector connector = createConnector(connectorDescription);
+ return Monitored.this.createSessionConfiguration(connector, repositoryName);
+ }
+
+ @Override
+ protected IManagedContainer getContainer()
+ {
+ return container;
+ }
+ };
+
+ agent.setMonitorConnector(createConnector("localhost:2038"));
+ agent.setConnectorDescription(host + ":" + port);
+ agent.setRepository(repository);
+ agent.setGroup(REPOSITORY_MONITOR_GROUP);
+ agent.setRate(500L);
+ agent.setTimeout(2000L);
+ agent.activate();
+
+ return repository;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Monitor
+ {
+ public static void main(String[] args) throws Exception
+ {
+ IManagedContainer container = createContainer();
+ FailoverMonitor monitor = (FailoverMonitor)container.getElement(FailoverMonitor.PRODUCT_GROUP, "net4j",
+ REPOSITORY_MONITOR_GROUP);
+
+ monitor.addListener(new ContainerEventAdapter<Pair<String, String>>()
+ {
+ @Override
+ protected void onAdded(IContainer<Pair<String, String>> monitor, Pair<String, String> agent)
+ {
+ dump((FailoverMonitor)monitor, "Added", agent);
+ }
+
+ @Override
+ protected void onRemoved(IContainer<Pair<String, String>> monitor, Pair<String, String> agent)
+ {
+ dump((FailoverMonitor)monitor, "Removed", agent);
+ }
+
+ private void dump(FailoverMonitor monitor, String event, Pair<String, String> agent)
+ {
+ System.out.println(event + " agent " + format(agent));
+ for (Entry<Protocol, Pair<String, String>> entry : monitor.getAgents().entrySet())
+ {
+ System.out.println(" " + (entry.getKey() == monitor.getMasterAgent() ? "MASTER: " : "BACKUP: ")
+ + format(entry.getValue()));
+ }
+ }
+
+ private String format(Pair<String, String> agent)
+ {
+ return agent.getElement1() + "/" + agent.getElement2();
+ }
+ });
+
+ container.getElement("org.eclipse.net4j.acceptors", TRANSPORT_TYPE, "0.0.0.0:2038");
+ System.out.println("Monitoring...");
+
+ for (;;)
+ {
+ Thread.sleep(100);
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Agent1 extends Monitored
+ {
+ public Agent1()
+ {
+ super("localhost", 2036, "repo1");
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ FailoverExample example = new Agent1();
+ example.init();
+ example.run();
+ example.done();
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Agent2 extends Monitored
+ {
+ public Agent2()
+ {
+ super("localhost", 2037, "repo2");
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ FailoverExample example = new Agent2();
+ example.init();
+ example.run();
+ example.done();
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server.net4j/META-INF/MANIFEST.MF
index 77d28f4ccd..9d35b1fa40 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/META-INF/MANIFEST.MF
@@ -14,4 +14,5 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)";resoluti
org.eclipse.net4j;bundle-version="[3.0.0,4.0.0)";visibility:=reexport
Export-Package: org.eclipse.emf.cdo.server.internal.net4j.bundle;version="4.0.0";x-internal:=true,
org.eclipse.emf.cdo.server.internal.net4j.protocol;version="4.0.0";x-friends:="org.eclipse.emf.cdo.tests",
+ org.eclipse.emf.cdo.server.internal.net4j.syncing;version="4.0.0",
org.eclipse.emf.cdo.server.net4j;version="4.0.0"
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/syncing/FailoverAgent.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/syncing/FailoverAgent.java
new file mode 100644
index 0000000000..6d436283d0
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/syncing/FailoverAgent.java
@@ -0,0 +1,286 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.internal.net4j.syncing;
+
+import org.eclipse.emf.cdo.common.CDOCommonRepository;
+import org.eclipse.emf.cdo.server.CDOServerUtil;
+import org.eclipse.emf.cdo.server.ISynchronizableRepository;
+import org.eclipse.emf.cdo.session.CDOSessionConfiguration;
+import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory;
+import org.eclipse.emf.cdo.spi.server.InternalFailoverParticipant;
+import org.eclipse.emf.cdo.spi.server.InternalRepositorySynchronizer;
+
+import org.eclipse.net4j.connector.IConnector;
+import org.eclipse.net4j.signal.Indication;
+import org.eclipse.net4j.signal.SignalReactor;
+import org.eclipse.net4j.signal.heartbeat.HeartBeatProtocol;
+import org.eclipse.net4j.util.concurrent.TimerLifecycle;
+import org.eclipse.net4j.util.concurrent.TimerLifecycle.DaemonFactory;
+import org.eclipse.net4j.util.container.IManagedContainer;
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.io.ExtendedDataInputStream;
+import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+
+import java.io.IOException;
+import java.util.Timer;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public abstract class FailoverAgent extends Lifecycle implements CDOSessionConfigurationFactory
+{
+ private IConnector monitorConnector;
+
+ private Timer timer;
+
+ private long rate;
+
+ private long timeout;
+
+ private String group;
+
+ private String connectorDescription;
+
+ private InternalFailoverParticipant repository;
+
+ private Protocol protocol;
+
+ private String masterConnectorDescription;
+
+ private String masterRepositoryName;
+
+ private InternalRepositorySynchronizer synchronizer;
+
+ public FailoverAgent()
+ {
+ }
+
+ public IConnector getMonitorConnector()
+ {
+ return monitorConnector;
+ }
+
+ public void setMonitorConnector(IConnector connector)
+ {
+ checkInactive();
+ monitorConnector = connector;
+ }
+
+ public Timer getTimer()
+ {
+ return timer;
+ }
+
+ public void setTimer(Timer timer)
+ {
+ checkInactive();
+ this.timer = timer;
+ }
+
+ public long getRate()
+ {
+ return rate;
+ }
+
+ public void setRate(long rate)
+ {
+ checkInactive();
+ this.rate = rate;
+ }
+
+ public long getTimeout()
+ {
+ return timeout;
+ }
+
+ public void setTimeout(long timeout)
+ {
+ checkInactive();
+ this.timeout = timeout;
+ }
+
+ public String getGroup()
+ {
+ return group;
+ }
+
+ public void setGroup(String group)
+ {
+ checkInactive();
+ this.group = group;
+ }
+
+ public String getConnectorDescription()
+ {
+ return connectorDescription;
+ }
+
+ public void setConnectorDescription(String connectorDescription)
+ {
+ checkInactive();
+ this.connectorDescription = connectorDescription;
+ }
+
+ public ISynchronizableRepository getRepository()
+ {
+ return repository;
+ }
+
+ public void setRepository(ISynchronizableRepository repository)
+ {
+ checkInactive();
+
+ if (!(repository instanceof InternalFailoverParticipant))
+ {
+ throw new IllegalArgumentException("Not a failover participant: " + repository);
+ }
+
+ if (repository.getSynchronizer() != null)
+ {
+ throw new IllegalArgumentException("Synchronizer must be null: " + repository);
+ }
+
+ this.repository = (InternalFailoverParticipant)repository;
+ }
+
+ public Protocol getProtocol()
+ {
+ return protocol;
+ }
+
+ public CDOSessionConfiguration createSessionConfiguration()
+ {
+ return createSessionConfiguration(masterConnectorDescription, masterRepositoryName);
+ }
+
+ @Override
+ protected void doBeforeActivate() throws Exception
+ {
+ super.doBeforeActivate();
+ checkState(monitorConnector, "monitorConnector");
+ checkState(group, "group");
+ checkState(connectorDescription, "connectorDescription");
+ checkState(repository, "repository");
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+
+ if (timer == null)
+ {
+ timer = (Timer)getContainer().getElement(TimerLifecycle.PRODUCT_GROUP, DaemonFactory.TYPE, null);
+ }
+
+ synchronizer = (InternalRepositorySynchronizer)CDOServerUtil.createRepositorySynchronizer(this);
+ repository.setSynchronizer(synchronizer);
+ setMaster(); // Will be adjusted with the following SIGNAL_PUBLISH_MASTER
+
+ LifecycleUtil.activate(repository);
+
+ protocol = new Protocol(this);
+ protocol.start(rate, timeout);
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ protocol.close();
+ protocol = null;
+ timer = null;
+ monitorConnector = null;
+ super.doDeactivate();
+ }
+
+ protected void setMaster()
+ {
+ repository.setType(CDOCommonRepository.Type.MASTER);
+ masterConnectorDescription = null;
+ masterRepositoryName = null;
+ }
+
+ protected void setBackup(String connectorDescription, String repositoryName)
+ {
+ masterConnectorDescription = connectorDescription;
+ masterRepositoryName = repositoryName;
+ repository.setType(CDOCommonRepository.Type.BACKUP);
+ }
+
+ protected abstract CDOSessionConfiguration createSessionConfiguration(String connectorDescription,
+ String repositoryName);
+
+ protected IManagedContainer getContainer()
+ {
+ return IPluginContainer.INSTANCE;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Protocol extends HeartBeatProtocol
+ {
+ private FailoverAgent agent;
+
+ public Protocol(FailoverAgent agent)
+ {
+ super(FailoverMonitor.PROTOCOL_NAME, agent.getMonitorConnector(), agent.getTimer());
+ this.agent = agent;
+ }
+
+ public FailoverAgent getAgent()
+ {
+ return agent;
+ }
+
+ @Override
+ protected void requestingStart(ExtendedDataOutputStream out, long rate) throws IOException
+ {
+ out.writeString(agent.getGroup());
+ out.writeString(agent.getConnectorDescription());
+ out.writeString(agent.getRepository().getName());
+ super.requestingStart(out, rate);
+ }
+
+ @Override
+ protected SignalReactor createSignalReactor(short signalID)
+ {
+ switch (signalID)
+ {
+ case FailoverMonitor.SIGNAL_PUBLISH_MASTER:
+ return new Indication(this, FailoverMonitor.SIGNAL_PUBLISH_MASTER)
+ {
+ @Override
+ protected void indicating(ExtendedDataInputStream in) throws Exception
+ {
+ boolean master = in.readBoolean();
+ if (master)
+ {
+ agent.setMaster();
+ }
+ else
+ {
+ String connectorDescription = in.readString();
+ String repositoryName = in.readString();
+ agent.setBackup(connectorDescription, repositoryName);
+ }
+ }
+ };
+
+ default:
+ return super.createSignalReactor(signalID);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/syncing/FailoverMonitor.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/syncing/FailoverMonitor.java
new file mode 100644
index 0000000000..a6b93056b6
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/syncing/FailoverMonitor.java
@@ -0,0 +1,271 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.internal.net4j.syncing;
+
+import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM;
+
+import org.eclipse.net4j.signal.Request;
+import org.eclipse.net4j.signal.heartbeat.HeartBeatProtocol;
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.container.Container;
+import org.eclipse.net4j.util.container.IManagedContainer;
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.factory.ProductCreationException;
+import org.eclipse.net4j.util.io.ExtendedDataInputStream;
+import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
+
+import org.eclipse.spi.net4j.ServerProtocolFactory;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public class FailoverMonitor extends Container<Pair<String, String>>
+{
+ public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.server.net4j.failoverMonitors";
+
+ public static final String PROTOCOL_NAME = "failover"; //$NON-NLS-1$
+
+ public static final short SIGNAL_PUBLISH_MASTER = 3;
+
+ private String group;
+
+ private Map<Protocol, Pair<String, String>> agents = new HashMap<Protocol, Pair<String, String>>();
+
+ private Protocol masterAgent;
+
+ public FailoverMonitor()
+ {
+ }
+
+ public String getGroup()
+ {
+ return group;
+ }
+
+ public void setGroup(String group)
+ {
+ checkInactive();
+ this.group = group;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Pair<String, String>[] getElements()
+ {
+ synchronized (agents)
+ {
+ return agents.values().toArray(new Pair[agents.size()]);
+ }
+ }
+
+ public Map<Protocol, Pair<String, String>> getAgents()
+ {
+ return Collections.unmodifiableMap(agents);
+ }
+
+ public Protocol getMasterAgent()
+ {
+ synchronized (agents)
+ {
+ return masterAgent;
+ }
+ }
+
+ public void registerAgent(Protocol agent, String connectorDescription, String repositoryName)
+ {
+ Pair<String, String> pair = new Pair<String, String>(connectorDescription, repositoryName);
+ synchronized (agents)
+ {
+ agents.put(agent, pair);
+ if (agents.size() == 1)
+ {
+ masterAgent = agent;
+ }
+
+ publishNewMaster(masterAgent);
+ }
+
+ fireElementAddedEvent(pair);
+ }
+
+ public void deregisterAgent(Protocol agent)
+ {
+ Pair<String, String> pair = null;
+ synchronized (agents)
+ {
+ pair = agents.remove(agent);
+ if (masterAgent == agent)
+ {
+ if (agents.isEmpty())
+ {
+ masterAgent = null;
+ }
+ else
+ {
+ masterAgent = electNewMaster(agents);
+ }
+
+ publishNewMaster(masterAgent);
+ }
+ }
+
+ if (pair != null)
+ {
+ fireElementRemovedEvent(pair);
+ }
+ }
+
+ @Override
+ protected void doBeforeActivate() throws Exception
+ {
+ super.doBeforeActivate();
+ checkState(group, "group");
+ }
+
+ protected Protocol electNewMaster(Map<Protocol, Pair<String, String>> agents)
+ {
+ return agents.keySet().iterator().next();
+ }
+
+ private void publishNewMaster(Protocol masterAgent)
+ {
+ final Pair<String, String> masterInfos = agents.get(masterAgent);
+ for (Protocol agent : agents.keySet())
+ {
+ final boolean master = agent == masterAgent;
+
+ try
+ {
+ new Request(agent, SIGNAL_PUBLISH_MASTER)
+ {
+ @Override
+ protected void requesting(ExtendedDataOutputStream out) throws Exception
+ {
+ if (master)
+ {
+ out.writeBoolean(true);
+ }
+ else
+ {
+ out.writeBoolean(false);
+ out.writeString(masterInfos.getElement1());
+ out.writeString(masterInfos.getElement2());
+ }
+ }
+ }.sendAsync();
+ }
+ catch (Exception ex)
+ {
+ OM.LOG.error(ex);
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public interface Provider
+ {
+ public FailoverMonitor getFailoverMonitor(String group);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Factory extends org.eclipse.net4j.util.factory.Factory
+ {
+ public Factory()
+ {
+ super(PRODUCT_GROUP, "net4j");
+ }
+
+ public FailoverMonitor create(String description) throws ProductCreationException
+ {
+ FailoverMonitor monitor = new FailoverMonitor();
+ monitor.setGroup(description);
+ return monitor;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Protocol extends HeartBeatProtocol.Server
+ {
+ private FailoverMonitor.Provider failoverMonitorProvider;
+
+ private FailoverMonitor failoverMonitor;
+
+ public Protocol(Provider failOverMonitorProvider)
+ {
+ super(PROTOCOL_NAME);
+ failoverMonitorProvider = failOverMonitorProvider;
+ }
+
+ @Override
+ protected void indicatingStart(ExtendedDataInputStream in) throws IOException
+ {
+ String group = in.readString();
+ String connectorDescription = in.readString();
+ String repositoryName = in.readString();
+
+ failoverMonitor = failoverMonitorProvider.getFailoverMonitor(group);
+ if (failoverMonitor == null)
+ {
+ throw new IllegalStateException("No monitor available for fail-over group " + group);
+ }
+
+ failoverMonitor.registerAgent(this, connectorDescription, repositoryName);
+ super.indicatingStart(in);
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ failoverMonitor.deregisterAgent(this);
+ super.doDeactivate();
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Factory extends ServerProtocolFactory implements FailoverMonitor.Provider
+ {
+ private IManagedContainer container;
+
+ public Factory(IManagedContainer container)
+ {
+ super(PROTOCOL_NAME);
+ this.container = container;
+ }
+
+ public Factory()
+ {
+ this(IPluginContainer.INSTANCE);
+ }
+
+ public Object create(String description) throws ProductCreationException
+ {
+ return new FailoverMonitor.Protocol(this);
+ }
+
+ public FailoverMonitor getFailoverMonitor(String group)
+ {
+ return (FailoverMonitor)container.getElement(FailoverMonitor.PRODUCT_GROUP, "net4j", group);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/net4j/CDONet4jServerUtil.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/net4j/CDONet4jServerUtil.java
index a2d643326c..c1b894dd29 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/net4j/CDONet4jServerUtil.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/net4j/CDONet4jServerUtil.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.server.net4j;
import org.eclipse.emf.cdo.server.IRepositoryProvider;
import org.eclipse.emf.cdo.server.internal.net4j.protocol.CDOServerProtocolFactory;
+import org.eclipse.emf.cdo.server.internal.net4j.syncing.FailoverMonitor;
import org.eclipse.emf.cdo.spi.server.ContainerRepositoryProvider;
import org.eclipse.net4j.util.container.IManagedContainer;
@@ -28,6 +29,8 @@ public final class CDONet4jServerUtil
public static void prepareContainer(IManagedContainer container, IRepositoryProvider repositoryProvider)
{
container.registerFactory(new CDOServerProtocolFactory(repositoryProvider));
+ container.registerFactory(new FailoverMonitor.Factory());
+ container.registerFactory(new FailoverMonitor.Protocol.Factory(container));
}
public static void prepareContainer(IManagedContainer container)
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/FailoverParticipant.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/FailoverParticipant.java
index ea9afbc236..f1a5052df1 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/FailoverParticipant.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/FailoverParticipant.java
@@ -11,12 +11,13 @@
package org.eclipse.emf.cdo.internal.server.syncing;
import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
+import org.eclipse.emf.cdo.spi.server.InternalFailoverParticipant;
import org.eclipse.emf.cdo.spi.server.InternalTransaction;
/**
* @author Eike Stepper
*/
-public class FailoverParticipant extends SynchronizableRepository
+public class FailoverParticipant extends SynchronizableRepository implements InternalFailoverParticipant
{
private boolean allowBackupCommits;
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java
index bd02a245bc..3e0376c632 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java
@@ -124,6 +124,23 @@ public final class CDOServerUtil
return createFailoverParticipant(name, store, props, synchronizer, master, false);
}
+ /**
+ * @since 4.0
+ */
+ public static ISynchronizableRepository createFailoverParticipant(String name, IStore store,
+ Map<String, String> props, IRepositorySynchronizer synchronizer)
+ {
+ return createFailoverParticipant(name, store, props, synchronizer, false);
+ }
+
+ /**
+ * @since 4.0
+ */
+ public static ISynchronizableRepository createFailoverParticipant(String name, IStore store, Map<String, String> props)
+ {
+ return createFailoverParticipant(name, store, props, null);
+ }
+
private static void initRepository(Repository repository, String name, IStore store, Map<String, String> props)
{
repository.setName(name);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalFailoverParticipant.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalFailoverParticipant.java
new file mode 100644
index 0000000000..5122a1a611
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalFailoverParticipant.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.server;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public interface InternalFailoverParticipant extends InternalSynchronizableRepository
+{
+ public boolean isAllowBackupCommits();
+
+ public void setAllowBackupCommits(boolean allowBackupCommits);
+}
diff --git a/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF
index aff31ac700..7cfbf44bde 100644
--- a/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.net4j;singleton:=true
-Bundle-Version: 3.0.100.qualifier
+Bundle-Version: 3.1.0.qualifier
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -11,7 +11,7 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ClassPath: .
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)";resolution:=optional,
org.eclipse.net4j.util;bundle-version="[3.0.0,4.0.0)";visibility:=reexport
-Export-Package: org.eclipse.internal.net4j;version="3.0.100";
+Export-Package: org.eclipse.internal.net4j;version="3.1.0";
x-friends:="org.eclipse.net4j.http.server,
org.eclipse.net4j.jvm,
org.eclipse.net4j.tcp,
@@ -20,7 +20,7 @@ Export-Package: org.eclipse.internal.net4j;version="3.0.100";
org.eclipse.net4j.http.tests,
org.eclipse.net4j.tests,
org.eclipse.net4j.defs",
- org.eclipse.internal.net4j.buffer;version="3.0.100";
+ org.eclipse.internal.net4j.buffer;version="3.1.0";
x-friends:="org.eclipse.net4j.http.server,
org.eclipse.net4j.jvm,
org.eclipse.net4j.tcp,
@@ -29,16 +29,16 @@ Export-Package: org.eclipse.internal.net4j;version="3.0.100";
org.eclipse.net4j.http.tests,
org.eclipse.net4j.tests,
org.eclipse.net4j.defs",
- org.eclipse.internal.net4j.bundle;version="3.0.100";x-internal:=true,
- org.eclipse.net4j;version="3.0.100",
- org.eclipse.net4j.acceptor;version="3.0.100",
- org.eclipse.net4j.buffer;version="3.0.100",
- org.eclipse.net4j.channel;version="3.0.100",
- org.eclipse.net4j.connector;version="3.0.100",
- org.eclipse.net4j.protocol;version="3.0.100",
- org.eclipse.net4j.signal;version="3.0.100",
- org.eclipse.net4j.signal.failover;version="3.0.100",
- org.eclipse.net4j.signal.heartbeat;version="3.0.100",
- org.eclipse.net4j.signal.wrapping;version="3.0.100",
- org.eclipse.spi.net4j;version="3.0.100"
+ org.eclipse.internal.net4j.bundle;version="3.1.0";x-internal:=true,
+ org.eclipse.net4j;version="3.1.0",
+ org.eclipse.net4j.acceptor;version="3.1.0",
+ org.eclipse.net4j.buffer;version="3.1.0",
+ org.eclipse.net4j.channel;version="3.1.0",
+ org.eclipse.net4j.connector;version="3.1.0",
+ org.eclipse.net4j.protocol;version="3.1.0",
+ org.eclipse.net4j.signal;version="3.1.0",
+ org.eclipse.net4j.signal.failover;version="3.1.0",
+ org.eclipse.net4j.signal.heartbeat;version="3.1.0",
+ org.eclipse.net4j.signal.wrapping;version="3.1.0",
+ org.eclipse.spi.net4j;version="3.1.0"
Eclipse-BuddyPolicy: registered
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/Net4jUtil.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/Net4jUtil.java
index ab637baf72..2213a3ff52 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/Net4jUtil.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/Net4jUtil.java
@@ -152,7 +152,7 @@ public final class Net4jUtil
*/
public static ITransportConfig copyTransportConfig(ILifecycle lifecycle, ITransportConfig source)
{
- return new TransportConfig(lifecycle, source.getReceiveExecutor(), source.getBufferProvider(), source
- .getProtocolProvider(), source.getNegotiator());
+ return new TransportConfig(lifecycle, source.getReceiveExecutor(), source.getBufferProvider(),
+ source.getProtocolProvider(), source.getNegotiator());
}
}
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/heartbeat/HeartBeatProtocol.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/heartbeat/HeartBeatProtocol.java
index 80c1ef895a..c1cec4fad4 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/heartbeat/HeartBeatProtocol.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/heartbeat/HeartBeatProtocol.java
@@ -32,6 +32,7 @@ import org.eclipse.internal.net4j.bundle.OM;
import org.eclipse.spi.net4j.ServerProtocolFactory;
+import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
@@ -53,15 +54,23 @@ public class HeartBeatProtocol extends SignalProtocol<Object>
private Timer timer;
- public HeartBeatProtocol(IConnector connector, Timer timer)
+ /**
+ * @since 3.1
+ */
+ protected HeartBeatProtocol(String type, IConnector connector, Timer timer)
{
- super(TYPE);
+ super(type);
checkArg(timer, "timer"); //$NON-NLS-1$
checkArg(connector, "connector"); //$NON-NLS-1$
this.timer = timer;
open(connector);
}
+ public HeartBeatProtocol(IConnector connector, Timer timer)
+ {
+ this(TYPE, connector, timer);
+ }
+
public HeartBeatProtocol(IConnector connector)
{
this(connector, getDefaultTimer(IPluginContainer.INSTANCE));
@@ -95,7 +104,7 @@ public class HeartBeatProtocol extends SignalProtocol<Object>
@Override
protected void requesting(ExtendedDataOutputStream out) throws Exception
{
- out.writeLong(rate);
+ requestingStart(out, rate);
}
}.sendAsync();
}
@@ -159,6 +168,14 @@ public class HeartBeatProtocol extends SignalProtocol<Object>
super.doDeactivate();
}
+ /**
+ * @since 3.1
+ */
+ protected void requestingStart(ExtendedDataOutputStream out, long rate) throws IOException
+ {
+ out.writeLong(rate);
+ }
+
public static Timer getDefaultTimer(IManagedContainer container)
{
return TimerLifecycle.DaemonFactory.getTimer(container, null);
@@ -175,9 +192,17 @@ public class HeartBeatProtocol extends SignalProtocol<Object>
private TimerTask heartBeatTimerTask;
+ /**
+ * @since 3.1
+ */
+ protected Server(String type)
+ {
+ super(type);
+ }
+
public Server()
{
- super(TYPE);
+ this(TYPE);
}
public Timer getHeartBeatTimer()
@@ -201,9 +226,7 @@ public class HeartBeatProtocol extends SignalProtocol<Object>
@Override
protected void indicating(ExtendedDataInputStream in) throws Exception
{
- heartBeatRate = in.readLong();
- cancelHeartBeatTask();
- scheduleHeartBeatTask();
+ indicatingStart(in);
}
};
}
@@ -225,6 +248,16 @@ public class HeartBeatProtocol extends SignalProtocol<Object>
super.doDeactivate();
}
+ /**
+ * @since 3.1
+ */
+ protected void indicatingStart(ExtendedDataInputStream in) throws IOException
+ {
+ heartBeatRate = in.readLong();
+ cancelHeartBeatTask();
+ scheduleHeartBeatTask();
+ }
+
private void scheduleHeartBeatTask()
{
heartBeatTimerTask = new TimerTask()

Back to the top