summaryrefslogtreecommitdiff
path: root/examples_java/src/db/repquote_gsg/RepQuoteExampleGSG.java
diff options
context:
space:
mode:
Diffstat (limited to 'examples_java/src/db/repquote_gsg/RepQuoteExampleGSG.java')
-rw-r--r--examples_java/src/db/repquote_gsg/RepQuoteExampleGSG.java383
1 files changed, 383 insertions, 0 deletions
diff --git a/examples_java/src/db/repquote_gsg/RepQuoteExampleGSG.java b/examples_java/src/db/repquote_gsg/RepQuoteExampleGSG.java
new file mode 100644
index 0000000..79740d7
--- /dev/null
+++ b/examples_java/src/db/repquote_gsg/RepQuoteExampleGSG.java
@@ -0,0 +1,383 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001-2009 Oracle. All rights reserved.
+ *
+ * $Id$
+ */
+
+// NOTE: This example is a simplified version of the RepQuoteExample.java
+// example that can be found in the db/examples_java/src/db/repquote directory.
+//
+// This example is intended only as an aid in learning Replication Manager
+// concepts. It is not complete in that many features are not exercised
+// in it, nor are many error conditions properly handled.
+
+package db.repquote_gsg;
+
+import java.io.FileNotFoundException;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.Thread;
+import java.lang.InterruptedException;
+
+import com.sleepycat.db.Cursor;
+import com.sleepycat.db.Database;
+import com.sleepycat.db.DatabaseConfig;
+import com.sleepycat.db.DatabaseEntry;
+import com.sleepycat.db.DatabaseException;
+import com.sleepycat.db.DeadlockException;
+import com.sleepycat.db.DatabaseType;
+import com.sleepycat.db.EnvironmentConfig;
+import com.sleepycat.db.EventHandler;
+import com.sleepycat.db.LockMode;
+import com.sleepycat.db.OperationStatus;
+import com.sleepycat.db.ReplicationHandleDeadException;
+import com.sleepycat.db.ReplicationHostAddress;
+import com.sleepycat.db.ReplicationManagerStartPolicy;
+import com.sleepycat.db.ReplicationManagerAckPolicy;
+import db.repquote_gsg.RepConfig;
+
+public class RepQuoteExampleGSG implements EventHandler
+{
+ private RepConfig repConfig;
+ private RepQuoteEnvironment dbenv;
+
+ public static void usage()
+ {
+ System.err.println("usage: " + RepConfig.progname);
+ System.err.println("-h home -l host:port [-r host:port]" +
+ "[-n nsites][-p priority]");
+
+ System.err.println("\t -h home directory (required)\n" +
+ "\t -l host:port (required; l stands for local)\n" +
+ "\t -r host:port (optional; r stands for remote; any " +
+ "number of these\n" +
+ "\t may be specified)\n" +
+ "\t -n nsites (optional; number of sites in replication " +
+ "group; defaults\n" +
+ "\t to 0 to try to dynamically compute nsites)\n" +
+ "\t -p priority (optional; defaults to 100)\n");
+
+ System.exit(1);
+ }
+
+ public static void main(String[] argv)
+ throws Exception
+ {
+ RepConfig config = new RepConfig();
+ String tmpHost;
+ int tmpPort = 0;
+ // Extract the command line parameters.
+ for (int i = 0; i < argv.length; i++)
+ {
+ if (argv[i].compareTo("-h") == 0) {
+ // home is a string arg.
+ i++;
+ config.home = argv[i];
+ } else if (argv[i].compareTo("-l") == 0) {
+ // "local" should be host:port.
+ i++;
+ String[] words = argv[i].split(":");
+ if (words.length != 2) {
+ System.err.println(
+ "Invalid host specification host:port needed.");
+ usage();
+ }
+ try {
+ tmpPort = Integer.parseInt(words[1]);
+ } catch (NumberFormatException nfe) {
+ System.err.println("Invalid host specification, " +
+ "could not parse port number.");
+ usage();
+ }
+ config.setThisHost(words[0], tmpPort);
+ } else if (argv[i].compareTo("-n") == 0) {
+ i++;
+ config.totalSites = Integer.parseInt(argv[i]);
+ } else if (argv[i].compareTo("-p") == 0) {
+ i++;
+ config.priority = Integer.parseInt(argv[i]);
+ } else if (argv[i].compareTo("-r") == 0) {
+ i++;
+ String[] words = argv[i].split(":");
+ if (words.length != 2) {
+ System.err.println(
+ "Invalid host specification host:port needed.");
+ usage();
+ }
+ try {
+ tmpPort = Integer.parseInt(words[1]);
+ } catch (NumberFormatException nfe) {
+ System.err.println("Invalid host specification, " +
+ "could not parse port number.");
+ usage();
+ }
+ config.addOtherHost(words[0], tmpPort);
+ } else {
+ System.err.println("Unrecognized option: " + argv[i]);
+ usage();
+ }
+
+ }
+
+ // Error check command line.
+ if ((!config.gotListenAddress()) || config.home.length() == 0)
+ usage();
+
+ RepQuoteExampleGSG runner = null;
+ try {
+ runner = new RepQuoteExampleGSG();
+ runner.init(config);
+
+ runner.doloop();
+ runner.terminate();
+ } catch (DatabaseException dbe) {
+ System.err.println("Caught an exception during " +
+ "initialization or processing: " + dbe.toString());
+ if (runner != null)
+ runner.terminate();
+ }
+ System.exit(0);
+ } // end main
+
+ public RepQuoteExampleGSG()
+ throws DatabaseException
+ {
+ repConfig = null;
+ dbenv = null;
+ }
+
+ public int init(RepConfig config)
+ throws DatabaseException
+ {
+ int ret = 0;
+ repConfig = config;
+ EnvironmentConfig envConfig = new EnvironmentConfig();
+ envConfig.setErrorStream(System.err);
+ envConfig.setErrorPrefix(RepConfig.progname);
+
+ envConfig.setReplicationManagerLocalSite(repConfig.getThisHost());
+ for (ReplicationHostAddress host = repConfig.getFirstOtherHost();
+ host != null; host = repConfig.getNextOtherHost())
+ envConfig.replicationManagerAddRemoteSite(host, false);
+
+ if (repConfig.totalSites > 0)
+ envConfig.setReplicationNumSites(repConfig.totalSites);
+ envConfig.setReplicationPriority(repConfig.priority);
+
+ envConfig.setReplicationManagerAckPolicy(
+ ReplicationManagerAckPolicy.ALL);
+ envConfig.setCacheSize(RepConfig.CACHESIZE);
+ envConfig.setTxnNoSync(true);
+
+ envConfig.setEventHandler(this);
+
+ envConfig.setAllowCreate(true);
+ envConfig.setRunRecovery(true);
+ envConfig.setThreaded(true);
+ envConfig.setInitializeReplication(true);
+ envConfig.setInitializeLocking(true);
+ envConfig.setInitializeLogging(true);
+ envConfig.setInitializeCache(true);
+ envConfig.setTransactional(true);
+ try {
+ dbenv = new RepQuoteEnvironment(repConfig.getHome(), envConfig);
+ } catch(FileNotFoundException e) {
+ System.err.println("FileNotFound exception: " + e.toString());
+ System.err.println(
+ "Ensure that the environment directory is pre-created.");
+ ret = 1;
+ }
+
+ // Start Replication Manager.
+ dbenv.replicationManagerStart(3, repConfig.startPolicy);
+ return ret;
+ }
+
+ // Provides the main data processing function for our application.
+ // This function provides a command line prompt to which the user
+ // can provide a ticker string and a stock price. Once a value is
+ // entered to the application, the application writes the value to
+ // the database and then displays the entire database.
+ public int doloop()
+ throws DatabaseException
+ {
+ Database db = null;
+
+ for (;;)
+ {
+ if (db == null) {
+ DatabaseConfig dbconf = new DatabaseConfig();
+ dbconf.setType(DatabaseType.BTREE);
+ if (dbenv.getIsMaster()) {
+ dbconf.setAllowCreate(true);
+ }
+ dbconf.setTransactional(true);
+
+ try {
+ db = dbenv.openDatabase
+ (null, RepConfig.progname, null, dbconf);
+ } catch (java.io.FileNotFoundException e) {
+ System.err.println("No stock database available yet.");
+ if (db != null) {
+ db.close(true);
+ db = null;
+ }
+ try {
+ Thread.sleep(RepConfig.SLEEPTIME);
+ } catch (InterruptedException ie) {}
+ continue;
+ }
+ }
+
+ BufferedReader stdin =
+ new BufferedReader(new InputStreamReader(System.in));
+
+ // Listen for input, and add it to the database.
+ System.out.print("QUOTESERVER");
+ if (!dbenv.getIsMaster())
+ System.out.print("(read-only)");
+ System.out.print("> ");
+ System.out.flush();
+ String nextline = null;
+ try {
+ nextline = stdin.readLine();
+ } catch (IOException ioe) {
+ System.err.println("Unable to get data from stdin");
+ break;
+ }
+ String[] words = nextline.split("\\s");
+
+ // A blank line causes the DB to be dumped to stdout.
+ if (words.length == 0 ||
+ (words.length == 1 && words[0].length() == 0)) {
+ try {
+ printStocks(db);
+ } catch (DeadlockException de) {
+ continue;
+ // Dead replication handles are cased by an election
+ // resulting in a previously committing read becoming
+ // invalid. Close the db handle and reopen.
+ } catch (ReplicationHandleDeadException rhde) {
+ db.close(true); // close no sync.
+ db = null;
+ continue;
+ } catch (DatabaseException e) {
+ System.err.println("Got db exception reading replication" +
+ "DB: " + e.toString());
+ break;
+ }
+ continue;
+ }
+
+ if (words.length == 1 &&
+ (words[0].compareToIgnoreCase("quit") == 0 ||
+ words[0].compareToIgnoreCase("exit") == 0)) {
+ break;
+ } else if (words.length != 2) {
+ System.err.println("Format: TICKER VALUE");
+ continue;
+ }
+
+ if (!dbenv.getIsMaster()) {
+ System.err.println("Can't update client.");
+ continue;
+ }
+
+ DatabaseEntry key = new DatabaseEntry(words[0].getBytes());
+ DatabaseEntry data = new DatabaseEntry(words[1].getBytes());
+
+ db.put(null, key, data);
+ }
+ if (db != null)
+ db.close(true);
+ return 0;
+ }
+
+ public void terminate()
+ throws DatabaseException
+ {
+ dbenv.close();
+ }
+
+ public void handleRepClientEvent()
+ {
+ dbenv.setIsMaster(false);
+ }
+
+ public void handleRepMasterEvent()
+ {
+ dbenv.setIsMaster(true);
+ }
+
+ public void handleRepNewMasterEvent(int envId)
+ {
+ // Ignored for now.
+ }
+
+ public void handleWriteFailedEvent(int errorCode)
+ {
+ System.err.println("Write to stable storage failed!" +
+ "Operating system error code:" + errorCode);
+ System.err.println("Continuing....");
+ }
+
+ public void handleRepStartupDoneEvent()
+ {
+ // Ignored for now.
+ }
+
+ public void handleRepPermFailedEvent()
+ {
+ // Ignored for now.
+ }
+
+ public void handleRepElectedEvent()
+ {
+ // Safely ignored for Replication Manager applications.
+ }
+
+ public void handlePanicEvent()
+ {
+ System.err.println("Panic encountered!");
+ System.err.println("Shutting down.");
+ System.err.println("You should restart, running recovery.");
+ try {
+ terminate();
+ } catch (DatabaseException dbe) {
+ System.err.println("Caught an exception during " +
+ "termination in handlePanicEvent: " + dbe.toString());
+ }
+ System.exit(-1);
+ }
+
+ // Display all the stock quote information in the database.
+ // Return type is void because error conditions are propagated
+ // via exceptions.
+ private void printStocks(Database db)
+ throws DeadlockException, DatabaseException
+ {
+ Cursor dbc = db.openCursor(null, null);
+
+ System.out.println("\tSymbol\tPrice");
+ System.out.println("\t======\t=====");
+
+ DatabaseEntry key = new DatabaseEntry();
+ DatabaseEntry data = new DatabaseEntry();
+ OperationStatus ret;
+ for (ret = dbc.getFirst(key, data, LockMode.DEFAULT);
+ ret == OperationStatus.SUCCESS;
+ ret = dbc.getNext(key, data, LockMode.DEFAULT)) {
+ String keystr = new String
+ (key.getData(), key.getOffset(), key.getSize());
+ String datastr = new String
+ (data.getData(), data.getOffset(), data.getSize());
+ System.out.println("\t"+keystr+"\t"+datastr);
+ }
+ dbc.close();
+ }
+} // end class
+