You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by rm...@apache.org on 2011/05/21 16:22:36 UTC

svn commit: r1125712 [1/2] - in /incubator/isis/trunk/runtimes/dflt/objectstores/nosql: ./ config/ src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/ src/main/java/...

Author: rmatthews
Date: Sat May 21 14:22:35 2011
New Revision: 1125712

URL: http://svn.apache.org/viewvc?rev=1125712&view=rev
Log:
1) Added alternative encryption methods
2) Added checksumming of stored object data
3) Recovery logs are now applied on startup and can be run manually
4) Secondary server can be synchronised with changes from a primary server

Added:
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncryption.java   (contents, props changed)
      - copied, changed from r1103224, incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncrypter.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/AesEncryption.java   (with props)
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionAbstract.java   (with props)
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingConfiguration.java   (with props)
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingKeyFile.java   (with props)
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/Rot13Encryption.java   (contents, props changed)
      - copied, changed from r1125067, incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/Rot13Encryption.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/ChecksummingPerfomance.java   (contents, props changed)
      - copied, changed from r1125067, incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/TestChecksumming.java
Removed:
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncrypter.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/Rot13Encryption.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/TestChecksumming.java
Modified:
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/config/server.properties
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/pom.xml
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoEncryption.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlCreateObjectCommand.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStore.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlPersistorMechanismInstaller.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlSaveObjectCommand.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReader.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommand.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/DataFileWriter.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileContent.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServer.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServerProcessor.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/LogWriter.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/Util.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStoreTest.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReaderTest.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommandTest.java
    incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/LogWriterTest.java

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/config/server.properties
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/config/server.properties?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/config/server.properties (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/config/server.properties Sat May 21 14:22:35 2011
@@ -16,6 +16,10 @@
 #  under the License.
 fileserver.host = localhost
 fileserver.port = 9100
+fileserver.control-host=localhost
+fileserver.control-port = 9101
+fileserver.sync-host=localhost
+fileserver.sync-port = 9102
 
 #fileserver.data = data
 #fileserver.services = services

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/pom.xml
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/pom.xml?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/pom.xml (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/pom.xml Sat May 21 14:22:35 2011
@@ -171,6 +171,11 @@
             <groupId>org.apache.isis.runtimes.dflt</groupId>
             <artifactId>runtime</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>commons-cli</groupId>
+            <artifactId>commons-cli</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>org.mongodb</groupId>

Copied: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncryption.java (from r1103224, incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncrypter.java)
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncryption.java?p2=incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncryption.java&p1=incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncrypter.java&r1=1103224&r2=1125712&rev=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncrypter.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncryption.java Sat May 21 14:22:35 2011
@@ -18,13 +18,18 @@
  */
 package org.apache.isis.runtimes.dflt.objectstores.nosql;
 
-public interface DataEncrypter {
+import org.apache.isis.core.commons.config.IsisConfiguration;
+
+public interface DataEncryption {
     
     String getType();
     
+    void init(IsisConfiguration configuration);
+
     String encrypt(String plainText);
     
     String decrypt(String encryptedText);
 
+
 }
 

Propchange: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/DataEncryption.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoEncryption.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoEncryption.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoEncryption.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoEncryption.java Sat May 21 14:22:35 2011
@@ -18,11 +18,16 @@
  */
 package org.apache.isis.runtimes.dflt.objectstores.nosql;
 
-public class NoEncryption implements DataEncrypter {
+import org.apache.isis.core.commons.config.IsisConfiguration;
+
+
+public class NoEncryption implements DataEncryption {
 
     public String getType() {
         return "none";
     }
+    
+    public void init(IsisConfiguration configuration) {}
 
     public String encrypt(String plainText) {
         return plainText;

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlCreateObjectCommand.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlCreateObjectCommand.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlCreateObjectCommand.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlCreateObjectCommand.java Sat May 21 14:22:35 2011
@@ -26,7 +26,7 @@ final class NoSqlCreateObjectCommand ext
     public NoSqlCreateObjectCommand(
             final KeyCreator keyCreator,
             final VersionCreator versionCreator,
-            final DataEncrypter dataEncrypter,
+            final DataEncryption dataEncrypter,
             final ObjectAdapter object) {
         super(false, keyCreator, versionCreator, dataEncrypter, object);
     }

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStore.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStore.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStore.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStore.java Sat May 21 14:22:35 2011
@@ -51,8 +51,8 @@ public class NoSqlObjectStore implements
     private final VersionCreator versionCreator;
     private final ObjectReader objectReader = new ObjectReader();
     private final NoSqlOidGenerator oidGenerator;
-    private final DataEncrypter wrtingDataEncrypter;
-    private final Map<String, DataEncrypter> availableDataEncrypters;
+    private final DataEncryption wrtingDataEncrypter;
+    private final Map<String, DataEncryption> availableDataEncrypters;
     private final boolean isDataLoaded;
 
     public NoSqlObjectStore(
@@ -60,8 +60,8 @@ public class NoSqlObjectStore implements
             final NoSqlOidGenerator oidGenerator,
             final KeyCreator keyCreator,
             final VersionCreator versionCreator,
-            final DataEncrypter writingDataEncrypter,
-            final Map<String, DataEncrypter> availableDataEncrypters) {
+            final DataEncryption writingDataEncrypter,
+            final Map<String, DataEncryption> availableDataEncrypters) {
         this.database = db;
         this.oidGenerator = oidGenerator;
         this.keyCreator = keyCreator;

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlPersistorMechanismInstaller.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlPersistorMechanismInstaller.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlPersistorMechanismInstaller.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlPersistorMechanismInstaller.java Sat May 21 14:22:35 2011
@@ -22,7 +22,10 @@ package org.apache.isis.runtimes.dflt.ob
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.isis.core.commons.config.ConfigurationConstants;
 import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterFactory;
 import org.apache.isis.runtimes.dflt.runtime.installerregistry.installerapi.ObjectStorePersistenceMechanismInstallerAbstract;
 import org.apache.isis.runtimes.dflt.runtime.persistence.PersistenceSessionFactoryDelegating;
@@ -31,9 +34,14 @@ import org.apache.isis.runtimes.dflt.run
 import org.apache.isis.runtimes.dflt.runtime.system.persistence.AdapterManager;
 import org.apache.isis.runtimes.dflt.runtime.system.persistence.OidGenerator;
 import org.apache.isis.runtimes.dflt.runtime.system.persistence.PersistenceSessionFactory;
+import org.apache.log4j.Logger;
 
 public abstract class NoSqlPersistorMechanismInstaller extends ObjectStorePersistenceMechanismInstallerAbstract {
 
+    private static final Logger LOG = Logger.getLogger(NoSqlPersistorMechanismInstaller.class);
+
+    private static final String NAKEDOBJECTS_ENCRYPTION_CLASSES = ConfigurationConstants.ROOT  + "nosql.encryption";
+
     private NoSqlObjectStore objectStore;
 
     public NoSqlPersistorMechanismInstaller(final String name) {
@@ -64,13 +72,33 @@ public abstract class NoSqlPersistorMech
             final NoSqlDataDatabase db = createNoSqlDatabase(configuration);
             final NoSqlOidGenerator oidGenerator = createOidGenerator(db);
             
-            DataEncrypter writingDataEncrypter = new Rot13Encryption();
-            Map<String, DataEncrypter> availableDataEncrypters = new HashMap<String, DataEncrypter>();
-            availableDataEncrypters.put(writingDataEncrypter.getType(), writingDataEncrypter);
-            DataEncrypter passThoughEncrypter = new NoEncryption();
-            availableDataEncrypters.put(passThoughEncrypter.getType(), passThoughEncrypter);
-            
-            objectStore = new NoSqlObjectStore(db, oidGenerator, keyCreator, versionCreator, writingDataEncrypter, availableDataEncrypters);
+            Map<String, DataEncryption> availableDataEncryption = new HashMap<String, DataEncryption>();
+            try {
+                final String[] encryptionClasses = getConfiguration().getList(NAKEDOBJECTS_ENCRYPTION_CLASSES);
+                DataEncryption writeWithEncryption = null;
+                boolean encryptionSpecified = false;
+                for (final String fullyQualifiedClass : encryptionClasses) {
+                    LOG.info("  adding encryption " + fullyQualifiedClass);
+                    final DataEncryption encryption = (DataEncryption) InstanceUtil.createInstance(fullyQualifiedClass);
+                    encryption.init(configuration);
+                    availableDataEncryption.put(encryption.getType(), encryption);
+                    if (!encryptionSpecified) {
+                        writeWithEncryption = encryption;
+                    }
+                    encryptionSpecified = true;
+                }
+                if (!encryptionSpecified) {
+                    LOG.warn("No encryption specified");
+                    final DataEncryption encryption = new NoEncryption();
+                    availableDataEncryption.put(encryption.getType(), encryption);
+                    writeWithEncryption = encryption;
+                }
+                objectStore = new NoSqlObjectStore(db, oidGenerator, keyCreator, versionCreator, writeWithEncryption, availableDataEncryption);
+            } catch (final IllegalArgumentException e) {
+                throw new IsisException(e);
+            } catch (final SecurityException e) {
+                throw new IsisException(e);
+            }
         }
         return objectStore;
     }

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlSaveObjectCommand.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlSaveObjectCommand.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlSaveObjectCommand.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlSaveObjectCommand.java Sat May 21 14:22:35 2011
@@ -26,7 +26,7 @@ final class NoSqlSaveObjectCommand exten
     public NoSqlSaveObjectCommand(
             final KeyCreator keyCreator,
             final VersionCreator versionCreator,
-            final DataEncrypter dataEncrypter,
+            final DataEncryption dataEncrypter,
             final ObjectAdapter object) {
         super(true, keyCreator, versionCreator, dataEncrypter, object);
     }

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReader.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReader.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReader.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReader.java Sat May 21 14:22:35 2011
@@ -44,7 +44,7 @@ class ObjectReader {
             final StateReader reader,
             final KeyCreator keyCreator,
             final VersionCreator versionCreator,
-            final Map<String, DataEncrypter> dataEncrypters) {
+            final Map<String, DataEncryption> dataEncrypters) {
         final String className = reader.readObjectType();
         final ObjectSpecification specification = IsisContext.getSpecificationLoader().loadSpecification(className);
         final String id = reader.readId();
@@ -77,7 +77,7 @@ class ObjectReader {
             final StateReader reader,
             final KeyCreator keyCreator,
             final VersionCreator versionCreator,
-            final Map<String, DataEncrypter> dataEncrypters,
+            final Map<String, DataEncryption> dataEncrypters,
             final ObjectAdapter object) {
         loadState(reader, keyCreator, versionCreator, dataEncrypters, object);
     }
@@ -86,7 +86,7 @@ class ObjectReader {
             final StateReader reader,
             final KeyCreator keyCreator,
             final VersionCreator versionCreator,
-            final Map<String, DataEncrypter> dataEncrypters,
+            final Map<String, DataEncryption> dataEncrypters,
             final ObjectAdapter object) {
     final ResolveState resolveState = ResolveState.RESOLVING;
         object.changeState(resolveState);
@@ -107,7 +107,7 @@ class ObjectReader {
             final StateReader reader,
             final ObjectAdapter object,
             final KeyCreator keyCreator,
-            final DataEncrypter dataEncrypter) {
+            final DataEncryption dataEncrypter) {
         final ObjectAssociationContainer specification = object.getSpecification();
         final List<ObjectAssociation> associations = specification.getAssociations();
         for (final ObjectAssociation association : associations) {
@@ -129,7 +129,7 @@ class ObjectReader {
     private void readAggregate(
             final StateReader reader,
             final KeyCreator keyCreator,
-            final DataEncrypter dataEncrypter,
+            final DataEncryption dataEncrypter,
             final OneToOneAssociation association,
             final ObjectAdapter object) {
         final String id = association.getId();
@@ -148,7 +148,7 @@ class ObjectReader {
             final StateReader aggregateReader,
             final Oid oid,
             final KeyCreator keyCreator,
-            final DataEncrypter dataEncrypter) {
+            final DataEncryption dataEncrypter) {
         final String objectType = aggregateReader.readObjectType();
         final ObjectSpecification specification = IsisContext.getSpecificationLoader().loadSpecification(objectType);
         final ObjectAdapter fieldObject = getAdapter(specification, oid);
@@ -163,7 +163,7 @@ class ObjectReader {
 
     private void readValue(
             final StateReader reader,
-            final DataEncrypter dataEncrypter,
+            final DataEncryption dataEncrypter,
             final OneToOneAssociation association,
             final ObjectAdapter object) {
         final String fieldData = reader.readField(association.getId());
@@ -196,7 +196,7 @@ class ObjectReader {
     private void readCollection(
             final StateReader reader,
             final KeyCreator keyCreator,
-            final DataEncrypter dataEncrypter,
+            final DataEncryption dataEncrypter,
             final OneToManyAssociation association,
             final ObjectAdapter object) {
         final ObjectAdapter collection = association.get(object);

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommand.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommand.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommand.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommand.java Sat May 21 14:22:35 2011
@@ -38,14 +38,14 @@ class WriteObjectCommand implements Pers
     private final KeyCreator keyCreator;
     private final ObjectAdapter object;
     private final VersionCreator versionCreator;
-    private final DataEncrypter dataEncrypter;
+    private final DataEncryption dataEncrypter;
     private final boolean isUpdate;
 
     WriteObjectCommand(
             final boolean isUpdate,
             final KeyCreator keyCreator,
             final VersionCreator versionCreator,
-            final DataEncrypter dataEncrypter,
+            final DataEncryption dataEncrypter,
             final ObjectAdapter object) {
         this.isUpdate = isUpdate;
         this.keyCreator = keyCreator;

Added: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/AesEncryption.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/AesEncryption.java?rev=1125712&view=auto
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/AesEncryption.java (added)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/AesEncryption.java Sat May 21 14:22:35 2011
@@ -0,0 +1,70 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.runtimes.dflt.objectstores.nosql.encryption;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.runtimes.dflt.objectstores.nosql.DataEncryption;
+import org.apache.isis.runtimes.dflt.objectstores.nosql.NoSqlStoreException;
+
+/**
+ * NOTE this does not work at the moment
+ */
+public class AesEncryption implements DataEncryption {
+
+    private static final String AES = "AES";
+    private final byte[] specKey;
+    
+    public AesEncryption() {
+        specKey = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+                0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
+    }
+
+    public void init(IsisConfiguration configuration) {}
+    
+    public String getType() {
+        return AES;
+    }
+
+    public String encrypt(String plainText) {
+        try {
+            SecretKeySpec key = new SecretKeySpec(specKey, AES);
+            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
+            cipher.init(Cipher.ENCRYPT_MODE, key);
+            return new String(cipher.doFinal(plainText.getBytes()));
+        } catch (Exception e) {
+            throw new NoSqlStoreException(e);
+        }
+    }
+
+    public String decrypt(String encryptedText) {
+        try {
+            SecretKeySpec key = new SecretKeySpec(specKey, AES);
+            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
+            cipher.init(Cipher.DECRYPT_MODE, key);
+            byte[] decrypted = cipher.doFinal(encryptedText.getBytes());
+            return new String(decrypted);
+        } catch (Exception e) {
+            throw new NoSqlStoreException(e);
+        }
+    }
+
+}

Propchange: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/AesEncryption.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionAbstract.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionAbstract.java?rev=1125712&view=auto
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionAbstract.java (added)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionAbstract.java Sat May 21 14:22:35 2011
@@ -0,0 +1,67 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.runtimes.dflt.objectstores.nosql.encryption;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.runtimes.dflt.objectstores.nosql.DataEncryption;
+import org.apache.isis.runtimes.dflt.objectstores.nosql.NoSqlStoreException;
+
+
+public abstract class BlowfishEncryptionAbstract implements DataEncryption {
+
+    private static final String BLOWFISH = "Blowfish";
+    private byte[] specKey;
+    
+    public void init(IsisConfiguration configuration) {
+        specKey = secretKey(configuration);
+    }
+
+    public abstract byte[] secretKey(IsisConfiguration configuration);
+
+    public String getType() {
+        return BLOWFISH;
+    }
+
+    public String encrypt(final String plainText) {
+        try {
+            SecretKeySpec key = new SecretKeySpec(specKey, BLOWFISH);
+            Cipher cipher = Cipher.getInstance(BLOWFISH);
+            cipher.init(Cipher.ENCRYPT_MODE, key);
+            return new String(cipher.doFinal(plainText.getBytes()));
+        } catch (Exception e) {
+            throw new NoSqlStoreException(e);
+        }
+    }
+
+    public String decrypt(final String encryptedText) {
+        try {
+            SecretKeySpec key = new SecretKeySpec(specKey, BLOWFISH);
+            Cipher cipher = Cipher.getInstance(BLOWFISH);
+            cipher.init(Cipher.DECRYPT_MODE, key);
+            byte[] decrypted = cipher.doFinal(encryptedText.getBytes());
+            return new String(decrypted);
+        } catch (Exception e) {
+            throw new NoSqlStoreException(e);
+        }
+    }
+
+}

Propchange: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionAbstract.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingConfiguration.java?rev=1125712&view=auto
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingConfiguration.java (added)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingConfiguration.java Sat May 21 14:22:35 2011
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.runtimes.dflt.objectstores.nosql.encryption;
+
+import org.apache.isis.core.commons.config.ConfigurationConstants;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.runtimes.dflt.objectstores.nosql.NoSqlStoreException;
+
+
+public class BlowfishEncryptionUsingConfiguration extends BlowfishEncryptionAbstract {
+
+    private static final String ENCRYPTION_KEY = ConfigurationConstants.ROOT  + "nosql.encryption.blowfish-key";
+
+    public byte[] secretKey(IsisConfiguration configuration) {
+        String key = configuration.getString(ENCRYPTION_KEY);
+        if (key == null) {
+            throw new NoSqlStoreException("No blowfish encryption key specified in the configuration file (key: " + ENCRYPTION_KEY + ")");
+        }
+        return key.getBytes();
+    }
+
+}

Propchange: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingConfiguration.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingKeyFile.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingKeyFile.java?rev=1125712&view=auto
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingKeyFile.java (added)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingKeyFile.java Sat May 21 14:22:35 2011
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.runtimes.dflt.objectstores.nosql.encryption;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.isis.core.commons.config.ConfigurationConstants;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.runtimes.dflt.objectstores.nosql.NoSqlStoreException;
+
+
+public class BlowfishEncryptionUsingKeyFile extends BlowfishEncryptionAbstract {
+
+    private static final String ENCRYPTION_KEY_FILE = ConfigurationConstants.ROOT + "nosql.encryption.blowfish-key-file";
+
+    public byte[] secretKey(IsisConfiguration configuration) {
+        String fileName = configuration.getString(ENCRYPTION_KEY_FILE, "./blowfish.key");
+        File file = new File(fileName);
+        if (file.exists()) {
+            try {
+                InputStream fileInput = new FileInputStream(file);
+                byte[] buffer = new byte[1024];
+                int length = fileInput.read(buffer);
+                byte[] key = new byte[length];
+                System.arraycopy(buffer, 0, key, 0, length);
+                return key;
+            } catch (IOException e) {
+                throw new NoSqlStoreException("Failed to read in encryption file: " + file.getAbsolutePath(), e);
+            }
+        } else {
+            throw new NoSqlStoreException("Cannot find encryption file: " + file.getAbsolutePath());
+        }
+    }
+
+}

Propchange: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/BlowfishEncryptionUsingKeyFile.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/Rot13Encryption.java (from r1125067, incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/Rot13Encryption.java)
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/Rot13Encryption.java?p2=incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/Rot13Encryption.java&p1=incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/Rot13Encryption.java&r1=1125067&r2=1125712&rev=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/Rot13Encryption.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/Rot13Encryption.java Sat May 21 14:22:35 2011
@@ -16,14 +16,19 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.runtimes.dflt.objectstores.nosql;
+package org.apache.isis.runtimes.dflt.objectstores.nosql.encryption;
 
-public class Rot13Encryption implements DataEncrypter {
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.runtimes.dflt.objectstores.nosql.DataEncryption;
+
+public class Rot13Encryption implements DataEncryption {
 
     public String getType() {
         return "rot13";
     }
 
+    public void init(IsisConfiguration configuration) {}
+    
     public String encrypt(String plainText) {
         return encode(plainText);
     }

Propchange: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/encryption/Rot13Encryption.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/DataFileWriter.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/DataFileWriter.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/DataFileWriter.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/DataFileWriter.java Sat May 21 14:22:35 2011
@@ -28,8 +28,6 @@ public class DataFileWriter {
 
     // private static final Logger LOG = Logger.getLogger(DataWriter.class);
 
-    private static final String ENCODING = "utf-8";
-
     private final List<FileContent> files;
 
     public DataFileWriter(final List<FileContent> files) {
@@ -56,26 +54,9 @@ public class DataFileWriter {
         }
         try {
             output = new FileOutputStream(file);
-            output.write(content.type.getBytes(ENCODING));
-            output.write(' ');
-            output.write(content.id.getBytes(ENCODING));
-            output.write(' ');
-            output.write(content.newVersion.getBytes(ENCODING));
-            output.write('\n');
-            output.write(content.data.getBytes(ENCODING));
+            content.write(output);
         } finally {
-            closeSafely(output);
-        }
-    }
-
-    private static void closeSafely(final FileOutputStream output) {
-        if (output != null) {
-            try {
-                output.flush();
-                output.close();
-            } catch (final IOException e) {
-                // throw new ObjectAdapterRuntimeException(e);
-            }
+            Util.closeSafely(output);
         }
     }
 

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileContent.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileContent.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileContent.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileContent.java Sat May 21 14:22:35 2011
@@ -19,8 +19,13 @@
 
 package org.apache.isis.runtimes.dflt.objectstores.nosql.file.server;
 
+import java.io.IOException;
+import java.io.OutputStream;
+
 class FileContent {
 
+    private static final String ENCODING = "utf-8";
+
     final char command;
     final String id;
     final String currentVersion;
@@ -38,4 +43,14 @@ class FileContent {
         this.data = buf;
     }
 
+    public void write(OutputStream output) throws IOException {
+        output.write(type.getBytes(ENCODING));
+        output.write(' ');
+        output.write(id.getBytes(ENCODING));
+        output.write(' ');
+        output.write(newVersion.getBytes(ENCODING));
+        output.write('\n');
+        output.write(data.getBytes(ENCODING));
+    }
+
 }

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServer.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServer.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServer.java Sat May 21 14:22:35 2011
@@ -19,15 +19,40 @@
 
 package org.apache.isis.runtimes.dflt.objectstores.nosql.file.server;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
 import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.ConnectException;
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;
-
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedInputStream;
+import java.util.zip.CheckedOutputStream;
+
+import org.apache.commons.cli.BasicParser;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
 import org.apache.commons.configuration.CompositeConfiguration;
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
@@ -36,38 +61,71 @@ import org.apache.isis.runtimes.dflt.obj
 import org.apache.log4j.Logger;
 import org.apache.log4j.PropertyConfigurator;
 
+
 public class FileServer {
 
     private static final Logger LOG = Logger.getLogger(FileServer.class);
     private static final String DEFAULT_HOST = "localhost";
-    private static final int DEFAULT_PORT = 9012;
+    private static final int DEFAULT_SERVICE_PORT = 9100;
+    private static final int DEFAULT_CONTROL_PORT = 9101;
+    private static final int DEFAULT_SYNC_PORT = 9102;
     private static final int BACKLOG = 0;
+    private static final int INIT = 1;
+    private static final int RECOVERY_LOG = 2;
+
+    public static void main(final String[] args) throws IOException, ParseException {
+
+        final Options options = new Options();
+        options.addOption("h", "help", false, "Show this help");
+        options.addOption("m", "mode", true, "mode: normal | recovery | secondary");
+
+        CommandLineParser parser = new BasicParser();
+        CommandLine cmd = parser.parse(options, args);
 
-    public static void main(final String[] args) throws IOException {
-        new FileServer().start();
+        if (cmd.hasOption('h')) {
+            printHelp(options);
+            return;
+        }
+
+        String mode = cmd.getOptionValue("m");
+
+        if ("recovery".equals(mode)) {
+            final FileServer fileServer = new FileServer();
+            fileServer.startRecovery(cmd.getArgList());
+        } else if ("secondary".equals(mode)) {
+            final FileServer fileServer = new FileServer();
+            fileServer.startSecondary();
+        } else if (mode == null || "normal".equals(mode)) {
+            final FileServer fileServer = new FileServer();
+            fileServer.startNormal();
+        } else {
+            printHelp(options);
+        }
+    }
+
+    private static void printHelp(final Options options) {
+        HelpFormatter help = new HelpFormatter();
+        help.printHelp("FileSever [OPTIONS] [FIRST RECOVERY FILES] [LAST RECOVERY FILES]", options);
     }
 
     private FileServerProcessor server;
-    private String host;
-    private int port;
-    private int connectionTimeout;
-    private int readTimeout;
+    private CompositeConfiguration config;
+
+    private boolean awaitConnections = true;
+    private boolean isQuiescent = false;
+    private long requests;
 
     public FileServer() {
         PropertyConfigurator.configure("config/logging.properties");
 
         try {
-            final CompositeConfiguration config = new CompositeConfiguration();
+            config = new CompositeConfiguration();
             config.addConfiguration(new SystemConfiguration());
             config.addConfiguration(new PropertiesConfiguration("config/server.properties"));
 
-            host = config.getString("fileserver.host", DEFAULT_HOST);
-            port = config.getInt("fileserver.port", DEFAULT_PORT);
             final String data = config.getString("fileserver.data");
             final String services = config.getString("fileserver.services");
             final String logs = config.getString("fileserver.logs");
-            connectionTimeout = config.getInt("fileserver.connection.timeout", 5000);
-            readTimeout = config.getInt("fileserver.read.timeout", 5000);
 
             Util.setDirectory(data, services, logs);
             server = new FileServerProcessor();
@@ -76,48 +134,88 @@ public class FileServer {
             System.out.println(e.getMessage());
             System.exit(0);
         }
+    }
+
+    private void startNormal() {
+        new Thread("control") {
+            public void run() {
+                startControl();
+            };
+        }.start();
+        new Thread("service") {
+            public void run() {
+                startService();
+            };
+        }.start();
+        new Thread("log-rolling") {
+            public void run() {
+                startLogRolling();
+            }
+        }.start();
+        if (config.getBoolean("fileserver.sync", false)) {
+            new Thread("sync") {
+                public void run() {
+                    startSyncing();
+                };
+            }.start();
+        } else {
+            LOG.info("not syncing to secondary server");
+        }
 
     }
 
-    private void start() {
+    private void startService() {
+        String serviceHost = config.getString("fileserver.host", DEFAULT_HOST);
+        int servicePort = config.getInt("fileserver.port", DEFAULT_SERVICE_PORT);
+        int connectionTimeout = config.getInt("fileserver.connection.timeout", 5000);
+        int readTimeout = config.getInt("fileserver.read.timeout", 5000);
+
         ServerSocket socket = null;
         try {
-            LOG.debug("setting up socket on " + host + ":" + port);
-            final InetAddress address = InetAddress.getByName(host);
-            socket = new ServerSocket(port, BACKLOG, address);
+            LOG.debug("setting up service socket on " + serviceHost + ":" + servicePort);
+            final InetAddress address = InetAddress.getByName(serviceHost);
+            socket = new ServerSocket(servicePort, BACKLOG, address);
             socket.setSoTimeout(connectionTimeout);
             LOG.info("listenting on " + socket.getInetAddress().getHostAddress() + " port " + socket.getLocalPort());
             LOG.debug("listenting on " + socket);
+            long lastRecoveryFile = lastRecoveryFile();
+            File file = Util.logFile(lastRecoveryFile);
+            LOG.info("replaying last recovery file: " + file.getAbsolutePath());
+            recover(file);
             server.startup();
         } catch (final UnknownHostException e) {
-            LOG.error("Unknown host " + host, e);
+            LOG.error("Unknown host " + serviceHost, e);
             System.exit(0);
         } catch (final IOException e) {
-            LOG.error("start failure - networking  not set up for " + host, e);
+            LOG.error("start failure - networking not set up for " + serviceHost, e);
             System.exit(0);
         } catch (final RuntimeException e) {
             LOG.error("start failure", e);
             System.exit(0);
         }
-        final boolean awaitConnections = true;
         do {
             try {
+                while (isQuiescent) {
+                    try {
+                        Thread.sleep(300);
+                    } catch (InterruptedException ignore) {}
+                }
                 final Socket connection = socket.accept();
                 LOG.info("connection from " + connection);
                 connection.setSoTimeout(readTimeout);
-                connection(connection);
-            } catch (final SocketTimeoutException expected) {
-            } catch (final IOException e) {
+                serviceConnection(connection, readTimeout);
+            } catch (final SocketTimeoutException expected) {} catch (final IOException e) {
                 LOG.error("networking problem", e);
             }
         } while (awaitConnections);
     }
 
-    private void connection(final Socket connection) {
+    private void serviceConnection(final Socket connection, final int readTimeout) {
         try {
             final InputStream input = connection.getInputStream();
             final OutputStream output = connection.getOutputStream();
             final ServerConnection pipe = new ServerConnection(input, output);
+            requests++;
             server.process(pipe);
             pipe.logComplete();
         } catch (final NoSqlStoreException e) {
@@ -137,10 +235,403 @@ public class FileServer {
                 LOG.warn("failure to close connection", e);
             }
         }
+    }
+
+    private void startSyncing() {
+        String syncHost = config.getString("fileserver.sync-host", DEFAULT_HOST);
+        int syncPort = config.getInt("fileserver.sync-port", DEFAULT_SYNC_PORT);
+        int connectionTimeout = config.getInt("fileserver.connection.timeout", 5000);
+
+        LOG.info("preparing to sync to secondary server on " + syncHost + " port " + syncPort);
+
+        final InetAddress address;
+        try {
+            address = InetAddress.getByName(syncHost);
+        } catch (final UnknownHostException e) {
+            LOG.error("Unknown host " + syncHost, e);
+            System.exit(0);
+            return;
+        }
+
+        while (awaitConnections) {
+            Socket socket = null;
+            try {
+                socket = new Socket(address, syncPort);
+                LOG.info("sync connected to " + socket.getInetAddress().getHostAddress() + " port " + socket.getLocalPort());
+
+                CRC32 crc32 = new CRC32();
+                DataOutput output = new DataOutputStream(new CheckedOutputStream(socket.getOutputStream(), crc32));
+                DataInput input = new DataInputStream(socket.getInputStream());
+                output.writeByte(INIT);
+                long logId = input.readLong();
+                do {
+                    long nextLogId = logId + 1;
+                    File file = Util.logFile(nextLogId);
+                    if (file.exists() && server.getLogger().isWritten(nextLogId)) {
+                        logId++;
+
+                        output.writeByte(RECOVERY_LOG);
+                        crc32.reset();
+                        output.writeLong(logId);
+
+                        LOG.info("sending recovery file: " + file.getName());
+                        BufferedInputStream fileInput = new BufferedInputStream(new FileInputStream(file));
+
+                        byte[] buffer = new byte[8092];
+                        int read;
+                        while ((read = fileInput.read(buffer)) > 0) {
+                            output.writeInt(read);
+                            output.write(buffer, 0, read);
+                        }
+                        output.writeInt(0);
+
+                        output.writeLong(crc32.getValue());
+                    }
+                    try {
+                        Thread.sleep(300);
+                    } catch (InterruptedException ignore) {}
+
+                    while (isQuiescent) {
+                        try {
+                            Thread.sleep(300);
+                        } catch (InterruptedException ignore) {}
+                    }
+                } while (awaitConnections);
+
+            } catch (final ConnectException e) {
+                LOG.warn("not yet connected to secondary server at " + syncHost + " port " + syncPort);
+                try {
+                    Thread.sleep(connectionTimeout);
+                } catch (InterruptedException ignore) {}
+            } catch (final IOException e) {
+                LOG.error("start failure - networking not set up for " + syncHost, e);
+                try {
+                    Thread.sleep(300);
+                } catch (InterruptedException ignore) {}
+            } catch (final RuntimeException e) {
+                LOG.error("start failure", e);
+                try {
+                    Thread.sleep(300);
+                } catch (InterruptedException ignore) {}
+            }
+        }
+
+    }
+
+    private void startControl() {
+        String controlHost = config.getString("fileserver.control-host", DEFAULT_HOST);
+        int controlPort = config.getInt("fileserver.control-port", DEFAULT_CONTROL_PORT);
+        int connectionTimeout = config.getInt("fileserver.connection.timeout", 5000);
+
+        ServerSocket socket = null;
+        try {
+            LOG.debug("setting up control socket on " + controlHost + ":" + controlPort);
+            final InetAddress address = InetAddress.getByName(controlHost);
+            socket = new ServerSocket(controlPort, 0, address);
+            socket.setSoTimeout(connectionTimeout);
+            LOG.info("listenting on " + socket.getInetAddress().getHostAddress() + " port " + socket.getLocalPort());
+            LOG.debug("listenting on " + socket);
+        } catch (final UnknownHostException e) {
+            LOG.error("Unknown host " + controlHost, e);
+            System.exit(0);
+        } catch (final IOException e) {
+            LOG.error("start failure - networking not set up for " + controlHost, e);
+            System.exit(0);
+        } catch (final RuntimeException e) {
+            LOG.error("start failure", e);
+            System.exit(0);
+        }
+        do {
+            try {
+                final Socket connection = socket.accept();
+                LOG.info("control connection from " + connection);
+                controlConnection(connection);
+            } catch (final SocketTimeoutException expected) {} catch (final IOException e) {
+                LOG.error("networking problem", e);
+            }
+        } while (awaitConnections);
+    }
+
+    private void controlConnection(final Socket connection) {
+        try {
+            final InputStream input = connection.getInputStream();
+            final BufferedReader reader = new BufferedReader(new InputStreamReader(input));
+            final OutputStream output = connection.getOutputStream();
+            final PrintWriter print = new PrintWriter(output);
+            print.print("> ");
+            print.flush();
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if ("shutdown".equals(line)) {
+                    awaitConnections = false;
+                    print.println("Server shutdown initiated...");
+                    print.flush();
+                    server.shutdown();
+                    break;
+                } else if ("quiesce".equals(line)) {
+                    isQuiescent = true;
+                    String message = "Placing server in a quiescent state";
+                    LOG.info(message);
+                    print.println(message);
+                    print.print("> ");
+                    print.flush();
+                } else if ("resume".equals(line)) {
+                    if (isQuiescent) {
+                        isQuiescent = false;
+                        String message = "Resuming from a quiescent state";
+                        LOG.info(message);
+                        print.println(message);
+                    } else {
+                        print.println("Can't resume as not currently in a quiescent state");
+                    }
+                    print.print("> ");
+                    print.flush();
+                } else if ("quit".equals(line)) {
+                    print.println("Bye");
+                    print.flush();
+                    break;
+                } else if ("status".equals(line)) {
+                    print.println("requests: " + requests);
+                    print.println("quiescent: " + isQuiescent);
+                    print.print("> ");
+                    print.flush();
+                } else {
+                    print.println("Unknown command, valid commands are: quit, quiesce, status, resume, shutdown");
+                    print.print("> ");
+                    print.flush();
+                }
+            }
+        } catch (final IOException e) {
+            LOG.error("networking failure", e);
+        } catch (final RuntimeException e) {
+            LOG.error("request failure", e);
+        } finally {
+            try {
+                connection.close();
+            } catch (final IOException e) {
+                LOG.warn("failure to close connection", e);
+            }
+        }
+    }
+
+    private void startRecovery(List list) {
+        LOG.info("starting recovery");
+        long lastId = lastRecoveryFile();
+        if (lastId < 0) {
+            System.err.println("No recovery files found");
+            System.exit(0);
+        }
+        LOG.info("last log file is " + Util.logFile(lastId).getName());
+
+        long startId = lastId;
+        long endId = lastId;
+
+        int size = list.size();
+        if (size > 0) {
+            startId = Long.valueOf((String) list.get(0));
+            if (size > 1) {
+                endId = Long.valueOf((String) list.get(1));
+            }
+        }
+        if (startId > lastId || endId > lastId) {
+            System.err.println("File IDs invalid: they must be less than or equal to " + lastId);
+            System.exit(0);
+        }
+        if (startId > endId) {
+            System.err.println("File IDs invalid: start must be before the end");
+            System.exit(0);
+        }
+
+        Util.ensureDirectoryExists();
+        for (long id = startId; id <= endId; id++) {
+            File file = Util.logFile(id);
+            LOG.info("recovering data from " + file.getName());
+            recover(file);
+        }
+    }
+
+    private long lastRecoveryFile() {
+        long lastId = -1;
+        while (Util.logFile(lastId + 1).exists()) {
+            lastId++;
+        }
+        return lastId;
+    }
+
+    private void startSecondary() {
+        String serviceHost = config.getString("fileserver.sync-host", DEFAULT_HOST);
+        int servicePort = config.getInt("fileserver.sync-port", DEFAULT_SYNC_PORT);
+
+        ServerSocket socket = null;
+        try {
+            LOG.debug("setting up syncing socket on " + serviceHost + ":" + servicePort);
+            final InetAddress address = InetAddress.getByName(serviceHost);
+            socket = new ServerSocket(servicePort, 0, address);
+            LOG.info("listenting on " + socket.getInetAddress().getHostAddress() + " port " + socket.getLocalPort());
+            LOG.debug("listenting on " + socket);
+            do {
+                syncConnection(socket.accept(), 0);
+            } while (awaitConnections);
+        } catch (final UnknownHostException e) {
+            LOG.error("Unknown host " + serviceHost, e);
+            System.exit(0);
+        } catch (final IOException e) {
+            LOG.error("start failure - networking not set up for " + serviceHost, e);
+            System.exit(0);
+        } catch (final RuntimeException e) {
+            LOG.error("start failure", e);
+            System.exit(0);
+        }
+    }
+
+    private void syncConnection(final Socket connection, final int readTimeout) {
+        try {
+            final CRC32 crc32 = new CRC32();
+            final DataOutput output = new DataOutputStream(connection.getOutputStream());
+            final DataInput input = new DataInputStream(new CheckedInputStream(connection.getInputStream(), crc32));
+
+            if (input.readByte() != INIT) {
+                return;
+            }
+
+            long lastId = lastRecoveryFile();
+            output.writeLong(lastId);
+            do {
+                if (input.readByte() != RECOVERY_LOG) {
+                    return;
+                }
+                crc32.reset();
+                long logId = input.readLong();
+                File file = Util.logFile(logId);
+                LOG.info("syncing recovery file: " + file.getName());
+                BufferedOutputStream fileOutput = new BufferedOutputStream(new FileOutputStream(file));
+
+                byte[] buffer = new byte[8092];
+                int length;
+                while ((length = input.readInt()) > 0) {
+                    input.readFully(buffer, 0, length);
+                    fileOutput.write(buffer, 0, length);
+                }
+                fileOutput.close();
+
+                long calculatedChecksum = crc32.getValue();
+                long sentChecksum = input.readLong();
+                if (calculatedChecksum != sentChecksum) {
+                    throw new NoSqlStoreException("Checksum didn't match during download of " + file.getName());
+                }
+
+                recover(file);
+
+            } while (true);
+        } catch (final NoSqlStoreException e) {
+            LOG.error("file server failure", e);
+        } catch (final IOException e) {
+            LOG.error("networking failure", e);
+        } catch (final RuntimeException e) {
+            LOG.error("request failure", e);
+        } finally {
+            try {
+                connection.close();
+            } catch (final IOException e) {
+                LOG.warn("failure to close connection", e);
+            }
+        }
+
+        // TODO restart
+    }
+
+    private void recover(File file) {
+        LineNumberReader reader = null;
+        try {
+            reader = new LineNumberReader(new InputStreamReader(new FileInputStream(file), Util.ENCODING));
+
+            while (true) {
+                String line = reader.readLine();
+                if (line == null) {
+                    break;
+                }
+                if (!line.startsWith("#transaction started")) {
+                    throw new NoSqlStoreException("No transaction start found: " + line + " (" + reader.getLineNumber() + ")");
+                }
+                readTransaction(reader);
+            }
+        } catch (IOException e) {
+            throw new NoSqlStoreException(e);
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    throw new NoSqlStoreException(e);
+                }
+            }
+        }
+    }
+
+    private void readTransaction(final LineNumberReader reader) throws IOException {
+        final ArrayList<FileContent> files = new ArrayList<FileContent>();
+        final DataFileWriter content = new DataFileWriter(files);
+        String header;
+        while ((header = reader.readLine()) != null) {
+            if (header.startsWith("#transaction ended")) {
+                LOG.info("transaction read in (ending " + reader.getLineNumber() + ")");
+                content.writeData();
+                reader.readLine();
+                return;
+            }
+            if (header.startsWith("S")) {
+                final String[] split = header.substring(1).split(" ");
+                final String key = split[0];
+                final String name = split[1];
+                server.saveService(key, name);
+                reader.readLine();
+            } else if (header.startsWith("B")) {
+                final String[] split = header.substring(1).split(" ");
+                final String name = split[0];
+                final long nextBatch = Long.valueOf(split[1]);
+                server.saveNextBatch(name, nextBatch);
+                reader.readLine();
+            } else {
+                FileContent elementData;
+                elementData = readElementData(header, reader);
+                files.add(elementData);
+            }
+        }
+        LOG.warn("transaction has no ending marker so is incomplete and will not be restored (ending " + reader.getLineNumber()
+                + ")");
+    }
 
+    private FileContent readElementData(final String header, final LineNumberReader reader) throws IOException {
+        StringBuffer content = new StringBuffer();
+        String line;
+        while ((line = reader.readLine()) != null) {
+            if (line.length() == 0) {
+                break;
+            }
+            content.append(line);
+            content.append('\n');
+        }
+
+        final char command = header.charAt(0);
+        final String[] split = header.substring(1).split(" ");
+        final String type = split[0];
+        final String id = split[1];
+        final String version = split[2];
+        return new FileContent(command, id, null, version, type, content.toString());
     }
 
-    private void shutdown() {
-        server.shutdown();
+    private void startLogRolling() {
+        int rollPeriod = config.getInt("fileserver.log-period", 5);
+        long sleepTime = rollPeriod * 60 * 1000;
+
+        while (awaitConnections) {
+            LogWriter logger = server.getLogger();
+            if (logger != null) {
+                logger.startNewFile();
+            }
+            try {
+                Thread.sleep(sleepTime);
+            } catch (InterruptedException ignore) {}
+        }
     }
 }

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServerProcessor.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServerProcessor.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServerProcessor.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/FileServerProcessor.java Sat May 21 14:22:35 2011
@@ -27,6 +27,7 @@ import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -53,6 +54,10 @@ public class FileServerProcessor {
         locks.waitUntilAllRealeased();
         logger.shutdown();
     }
+    
+    LogWriter getLogger() {
+        return logger;
+    }
 
     public void process(final ServerConnection connection) {
         try {
@@ -196,7 +201,7 @@ public class FileServerProcessor {
             files = getWriteRequests(connection);
             final String error = acquireLocks(files);
             if (error == null) {
-                logger.log(files);
+                logger.logWrites(files);
                 final DataFileWriter content = new DataFileWriter(files);
                 content.writeData();
                 connection.ok();
@@ -307,14 +312,20 @@ public class FileServerProcessor {
         connection.endCommand();
         final String name = connection.getRequest();
         final String key = connection.getRequest();
+        logger.logServiceEntry(key, name);
+        saveService(key, name);
+        connection.ok();
+    }
 
+    void saveService(final String key, final String name) throws FileNotFoundException, IOException,
+            UnsupportedEncodingException {
         FileOutputStream fileOut = null;
         final File file = Util.serviceFile(name);
         try {
             fileOut = new FileOutputStream(file);
-            fileOut.write(name.getBytes("utf-8"));
+            fileOut.write(name.getBytes(Util.ENCODING));
             fileOut.write(' ');
-            fileOut.write(key.getBytes("utf-8"));
+            fileOut.write(key.getBytes(Util.ENCODING));
         } finally {
             if (fileOut != null) {
                 try {
@@ -324,7 +335,6 @@ public class FileServerProcessor {
                 }
             }
         }
-        connection.ok();
     }
 
     private void nextSerialBatch(final ServerConnection connection) throws IOException {
@@ -347,16 +357,26 @@ public class FileServerProcessor {
             LOG.info("New ID batch allocated, from " + nextId);
         }
 
-        final FileOutputStream fileOutput = new FileOutputStream(file);
         final long newBatchAt = nextId + batchSize;
-        fileOutput.write(Long.toString(newBatchAt).getBytes("utf-8"));
-        fileOutput.close();
+        logger.logNextSerialBatch(name, newBatchAt);
+        
+        saveNextBatch(file, newBatchAt);
 
         // TODO remove lock
 
         connection.response(nextId);
     }
 
+    private void saveNextBatch(final File file, final long newBatchAt) throws FileNotFoundException, IOException {
+        final FileOutputStream fileOutput = new FileOutputStream(file);
+        fileOutput.write(Long.toString(newBatchAt).getBytes(Util.ENCODING));
+        fileOutput.close();
+    }
+
+    public void saveNextBatch(String name, long nextBatch) throws IOException {
+        saveNextBatch(Util.serialNumberFile(name), nextBatch);
+    }
+
     private void hasInstances(final ServerConnection connection) throws IOException {
         connection.endCommand();
         final String type = connection.getRequest();

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/LogWriter.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/LogWriter.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/LogWriter.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/LogWriter.java Sat May 21 14:22:35 2011
@@ -31,33 +31,59 @@ import org.apache.isis.runtimes.dflt.obj
 public class LogWriter {
 
     private DataOutputStream writer;
-    private boolean startNewFile = true;
-    private int fileIndex;
+    private boolean startNewFile = false;
+    private int nextLogIdToWrite;
 
     public void startNewFile() {
-        // TODO don't start new file if old one is empty
-        startNewFile = true;
+        // don't start new file if old one is empty
+        File file = Util.logFile(nextLogIdToWrite);
+        if (file.exists() && file.length() > 0) {
+            startNewFile = true;
+        }
     }
 
-    public synchronized void log(final List<FileContent> items) {
-        if (startNewFile) {
-            close();
-            openNewFile();
-            startNewFile = false;
+    public synchronized void logNextSerialBatch(String name, long newBatchAt) {
+        startNewFileIfNeeded();
+        try {
+            writer.write(("#transaction started - " + new Date().toString() + "\n").getBytes());
+            writer.write('B');
+            writer.write(name.getBytes(Util.ENCODING));
+            writer.write(' ');
+            writer.write(Long.toString(newBatchAt).getBytes(Util.ENCODING));
+            writer.write('\n');
+            writer.write('\n');
+            writer.write("#transaction ended\n\n".getBytes());
+            writer.flush();
+        } catch (final IOException e) {
+            throw new NoSqlStoreException("Failed to write serial number data to log file", e);
+        }
+
+    }
+
+    public synchronized void logServiceEntry(String key, String name) {
+        startNewFileIfNeeded();
+        try {
+            writer.write(("#transaction started - " + new Date().toString() + "\n").getBytes());
+            writer.write('S');
+            writer.write(key.getBytes(Util.ENCODING));
+            writer.write(' ');
+            writer.write(name.getBytes(Util.ENCODING));
+            writer.write('\n');
+            writer.write('\n');
+            writer.write("#transaction ended\n\n".getBytes());
+            writer.flush();
+        } catch (final IOException e) {
+            throw new NoSqlStoreException("Failed to write service entry data to log file", e);
         }
+    }
+
+    public synchronized void logWrites(final List<FileContent> items) {
+        startNewFileIfNeeded();
         try {
             writer.write(("#transaction started - " + new Date().toString() + "\n").getBytes());
             for (final FileContent content : items) {
                 writer.write(content.command);
-                writer.write(content.type.getBytes("utf-8"));
-                writer.write(' ');
-                writer.write(content.id.getBytes("utf-8"));
-                writer.write(' ');
-                writer.write(content.currentVersion.getBytes("utf-8"));
-                writer.write(' ');
-                writer.write('\n');
-                writer.write(content.data.getBytes("utf-8"));
-                writer.write('\n');
+                content.write(writer);
                 writer.write('\n');
             }
             writer.write("#transaction ended\n\n".getBytes());
@@ -67,11 +93,20 @@ public class LogWriter {
         }
     }
 
+    private void startNewFileIfNeeded() {
+        if (startNewFile) {
+            close();
+            openNewFile();
+            startNewFile = false;
+        }
+    }
+
     private void openNewFile() {
-        File file;
-        do {
-            file = Util.logFile(fileIndex++);
-        } while (file.exists());
+        File file = findNextFile();
+        openFile(file);
+    }
+
+    private void openFile(File file) {
         try {
             writer = new DataOutputStream(new FileOutputStream(file));
             startNewFile = false;
@@ -80,9 +115,25 @@ public class LogWriter {
         }
     }
 
+    private File findNextFile() {
+        File file;
+        do {
+            nextLogIdToWrite++;
+            file = Util.logFile(nextLogIdToWrite);
+        } while (file.exists());
+        return file;
+    }
+
     public void startup() {
-        // TODO replay log.
-        openNewFile();
+        findNextFile();
+        nextLogIdToWrite--;
+        startNewFile();
+        if (!startNewFile) {
+            File file = Util.logFile(nextLogIdToWrite);
+            openFile(file);
+        } else {
+            openNewFile();
+        }
     }
 
     public void shutdown() {
@@ -96,4 +147,9 @@ public class LogWriter {
             throw new NoSqlStoreException("Falied to close log file", e);
         }
     }
+
+    public synchronized boolean isWritten(long logId) {
+        startNewFileIfNeeded();
+        return logId < nextLogIdToWrite;
+    }
 }

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/Util.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/Util.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/Util.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/main/java/org/apache/isis/runtimes/dflt/objectstores/nosql/file/server/Util.java Sat May 21 14:22:35 2011
@@ -21,6 +21,7 @@ package org.apache.isis.runtimes.dflt.ob
 
 import java.io.File;
 import java.io.FileFilter;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -155,7 +156,7 @@ public class Util {
         return new File(dataDirectory, "serialnumbers" + name.trim() + ".data");
     }
 
-    static File logFile(final int id) {
+    static File logFile(final long id) {
         return new File(logDirectory, "recovery" + id + ".log");
     }
 
@@ -281,4 +282,16 @@ public class Util {
         };
     }
 
+
+    public static void closeSafely(final FileOutputStream output) {
+        if (output != null) {
+            try {
+                output.flush();
+                output.close();
+            } catch (final IOException e) {
+                // throw new ObjectAdapterRuntimeException(e);
+            }
+        }
+    }
+
 }

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStoreTest.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStoreTest.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStoreTest.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/NoSqlObjectStoreTest.java Sat May 21 14:22:35 2011
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.exceptions.UnexpectedCallException;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ResolveState;
@@ -78,12 +79,14 @@ public class NoSqlObjectStoreTest {
         keyCreator = context.mock(KeyCreator.class);
         versionCreator = context.mock(VersionCreator.class);
         
-        Map<String, DataEncrypter> dataEncrypter = new HashMap<String, DataEncrypter>();
-        DataEncrypter dataEncrypter1 = new DataEncrypter() {
+        Map<String, DataEncryption> dataEncrypter = new HashMap<String, DataEncryption>();
+        DataEncryption dataEncrypter1 = new DataEncryption() {
             public String getType() {
                 return "etc";
             }
 
+            public void init(IsisConfiguration configuration) {}
+            
             public String encrypt(String plainText) {
                 throw new UnexpectedCallException();
             }
@@ -133,7 +136,7 @@ public class NoSqlObjectStoreTest {
                 one(db).close();
             }
         });
-        store = new NoSqlObjectStore(db, new NoSqlOidGenerator(db), null, null, null, new HashMap<String, DataEncrypter>());
+        store = new NoSqlObjectStore(db, new NoSqlOidGenerator(db), null, null, null, new HashMap<String, DataEncryption>());
         assertTrue(store.isFixturesInstalled());
     }
 

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReaderTest.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReaderTest.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReaderTest.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/ObjectReaderTest.java Sat May 21 14:22:35 2011
@@ -23,6 +23,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.exceptions.UnexpectedCallException;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ResolveState;
@@ -49,7 +50,7 @@ public class ObjectReaderTest {
     private Mockery context;
     private KeyCreator keyCreator;
     private VersionCreator versionCreator;
-    private Map<String, DataEncrypter> dataEncrypter;
+    private Map<String, DataEncryption> dataEncrypter;
 
     @Before
     public void setup() {
@@ -64,12 +65,14 @@ public class ObjectReaderTest {
         versionCreator = context.mock(VersionCreator.class);
         
         
-        dataEncrypter = new HashMap<String, DataEncrypter>();
-        DataEncrypter dataEncrypter1 = new DataEncrypter() {
+        dataEncrypter = new HashMap<String, DataEncryption>();
+        DataEncryption dataEncrypter1 = new DataEncryption() {
             public String getType() {
                 return "etc1";
             }
 
+            public void init(IsisConfiguration configuration) {}
+            
             public String encrypt(String plainText) {
                 throw new UnexpectedCallException();
             }

Modified: incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommandTest.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommandTest.java?rev=1125712&r1=1125711&r2=1125712&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommandTest.java (original)
+++ incubator/isis/trunk/runtimes/dflt/objectstores/nosql/src/test/java/org/apache/isis/runtimes/dflt/objectstores/nosql/WriteObjectCommandTest.java Sat May 21 14:22:35 2011
@@ -19,6 +19,7 @@
 
 package org.apache.isis.runtimes.dflt.objectstores.nosql;
 
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.exceptions.UnexpectedCallException;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.version.SerialNumberVersion;
@@ -45,7 +46,7 @@ public class WriteObjectCommandTest {
     private KeyCreator keyCreator;
     private NoSqlCommandContext commandContext;
     private Mockery context;
-    private DataEncrypter dataEncrypter;
+    private DataEncryption dataEncrypter;
 
     @Before
     public void setup() {
@@ -97,11 +98,13 @@ public class WriteObjectCommandTest {
             }
         });
         
-        dataEncrypter = new DataEncrypter() {
+        dataEncrypter = new DataEncryption() {
             public String getType() {
                 return "etc1";
             }
-
+            
+            public void init(IsisConfiguration configuration) {}
+            
             public String encrypt(String plainText) {
                 return "ENC" + plainText;
             }