Added synchronisation and extra error checking for if provisioner is called multiple times in rapid succession.
diff --git a/service/src/main/java/io/mifos/identity/internal/command/handler/Provisioner.java b/service/src/main/java/io/mifos/identity/internal/command/handler/Provisioner.java
index ecf1c61..304092e 100644
--- a/service/src/main/java/io/mifos/identity/internal/command/handler/Provisioner.java
+++ b/service/src/main/java/io/mifos/identity/internal/command/handler/Provisioner.java
@@ -96,7 +96,7 @@
     this.saltGenerator = saltGenerator;
   }
 
-  public ApplicationSignatureSet provisionTenant(final String initialPasswordHash) {
+  public synchronized ApplicationSignatureSet provisionTenant(final String initialPasswordHash) {
     logger.info("Provisioning cassandra tables for tenant {}...", TenantContextHolder.checkedGetIdentifier());
     final RsaKeyPairFactory.KeyPairHolder keys = RsaKeyPairFactory.createKeyPair();
 
diff --git a/service/src/main/java/io/mifos/identity/internal/repository/Signatures.java b/service/src/main/java/io/mifos/identity/internal/repository/Signatures.java
index a54b003..040015d 100644
--- a/service/src/main/java/io/mifos/identity/internal/repository/Signatures.java
+++ b/service/src/main/java/io/mifos/identity/internal/repository/Signatures.java
@@ -39,6 +39,13 @@
 import java.util.stream.StreamSupport;
 
 /**
+ * All write accesses are synchronized.  These occur only during provisioning or key rotation, so they are not
+ * performance critical.  These are only necessary because for some reason (that I have not yet been able to track
+ * down), provisioning is being called multiple times in rapid succession for a tenant.
+ *
+ * All calls to cassandra which could conceivably be performed before provisioning is complete are surrounded by
+ * a try-catch block for an InvalidQueryException.  If provisioning is not completed, the table is treated as empty.
+ *
  * @author Myrle Krantz
  */
 @Component
@@ -63,7 +70,7 @@
     this.tenantAwareCassandraMapperProvider = tenantAwareCassandraMapperProvider;
   }
 
-  public void buildTable() {
+  public synchronized void buildTable() {
     final Create create = SchemaBuilder.createTable(TABLE_NAME)
         .ifNotExists()
         .addPartitionKey(KEY_TIMESTAMP_COLUMN, DataType.text())
@@ -83,7 +90,7 @@
     cassandraSessionProvider.getTenantSession().execute(createValidIndex);
   }
 
-  public SignatureEntity add(final RsaKeyPairFactory.KeyPairHolder keys)
+  public synchronized SignatureEntity add(final RsaKeyPairFactory.KeyPairHolder keys)
   {
     //There will only be one entry in this table.
     final BoundStatement tenantCreationStatement =
@@ -116,11 +123,16 @@
   }
 
   public Optional<SignatureEntity> getSignature(final String keyTimestamp) {
-    final Mapper<SignatureEntity> signatureEntityMapper
-            = tenantAwareCassandraMapperProvider.getMapper(SignatureEntity.class);
+    try {
+      final Mapper<SignatureEntity> signatureEntityMapper
+          = tenantAwareCassandraMapperProvider.getMapper(SignatureEntity.class);
 
-    final Optional<SignatureEntity> ret = Optional.ofNullable(signatureEntityMapper.get(keyTimestamp));
-    return ret.filter(SignatureEntity::getValid);
+      final Optional<SignatureEntity> ret = Optional.ofNullable(signatureEntityMapper.get(keyTimestamp));
+      return ret.filter(SignatureEntity::getValid);
+    }
+    catch (final InvalidQueryException e) {
+      return Optional.empty();
+    }
   }
 
   /**
@@ -128,25 +140,24 @@
    */
   public Optional<PrivateSignatureEntity> getPrivateSignature()
   {
-    try {
-      final Optional<String> maximumKeyTimestamp = streamValidKeyTimestamps().max(String::compareTo);
+    final Optional<String> maximumKeyTimestamp = streamValidKeyTimestamps().max(String::compareTo);
 
-      return maximumKeyTimestamp.flatMap(this::getPrivateSignatureEntity);
+    return maximumKeyTimestamp.flatMap(this::getPrivateSignatureEntity);
+  }
+
+  private Optional<PrivateSignatureEntity> getPrivateSignatureEntity(final String keyTimestamp) {
+    try {
+      final Mapper<PrivateSignatureEntity> privateSignatureEntityMapper
+          = tenantAwareCassandraMapperProvider.getMapper(PrivateSignatureEntity.class);
+
+      final Optional<PrivateSignatureEntity> ret = Optional.ofNullable(privateSignatureEntityMapper.get(keyTimestamp));
+      return ret.filter(PrivateSignatureEntity::getValid);
     }
     catch (final InvalidQueryException e) {
       return Optional.empty();
     }
   }
 
-  private Optional<PrivateSignatureEntity> getPrivateSignatureEntity(final String keyTimestamp) {
-
-    final Mapper<PrivateSignatureEntity> privateSignatureEntityMapper
-            = tenantAwareCassandraMapperProvider.getMapper(PrivateSignatureEntity.class);
-
-    final Optional<PrivateSignatureEntity> ret = Optional.ofNullable(privateSignatureEntityMapper.get(keyTimestamp));
-    return ret.filter(PrivateSignatureEntity::getValid);
-  }
-
   public List<String> getAllKeyTimestamps() {
       return streamValidKeyTimestamps().collect(Collectors.toList());
   }
@@ -165,9 +176,8 @@
     }
   }
 
-  public void invalidateEntry(final String keyTimestamp) {
+  public synchronized void invalidateEntry(final String keyTimestamp) {
     final Update.Assignments updateQuery = QueryBuilder.update(TABLE_NAME).where(QueryBuilder.eq(KEY_TIMESTAMP_COLUMN, keyTimestamp)).with(QueryBuilder.set(VALID_COLUMN, false));
     cassandraSessionProvider.getTenantSession().execute(updateQuery);
-
   }
 }