Rya-82 Rya Console updated to incorporate Rya Details for an instance and 
provide administrative commands.


Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/fcc98bd9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/fcc98bd9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/fcc98bd9

Branch: refs/heads/master
Commit: fcc98bd924b3dab0b4f9296058aed541d585eb9a
Parents: 57df230
Author: Kevin Chilton <[email protected]>
Authored: Mon Jul 18 15:10:05 2016 -0400
Committer: Aaron Mihalik <[email protected]>
Committed: Tue Aug 23 10:41:39 2016 -0400

----------------------------------------------------------------------
 common/rya.api/pom.xml                          |   5 +
 .../main/java/mvm/rya/api/client/CreatePCJ.java |  40 ++
 .../main/java/mvm/rya/api/client/DeletePCJ.java |  38 ++
 .../mvm/rya/api/client/GetInstanceDetails.java  |  44 ++
 .../main/java/mvm/rya/api/client/Install.java   | 268 ++++++++++++
 .../client/InstanceDoesNotExistException.java   |  38 ++
 .../java/mvm/rya/api/client/InstanceExists.java |  37 ++
 .../java/mvm/rya/api/client/ListInstances.java  |  38 ++
 .../main/java/mvm/rya/api/client/RyaClient.java | 101 +++++
 .../mvm/rya/api/client/RyaClientException.java  |  37 ++
 .../java/mvm/rya/api/instance/RyaDetails.java   | 141 ++++++-
 .../api/instance/RyaDetailsToConfiguration.java |   4 +-
 .../mvm/rya/api/instance/RyaDetailsUpdater.java | 124 ++++++
 .../mvm/rya/api/instance/RyaDetailsTest.java    |  21 +-
 .../instance/RyaDetailsToConfigurationTest.java |   7 +-
 .../rya/api/instance/RyaDetailsUpdaterTest.java | 141 +++++++
 dao/accumulo.rya/pom.xml                        |  14 +
 .../java/mvm/rya/accumulo/AccumuloRyaDAO.java   |  26 +-
 .../AccumuloRyaInstanceDetailsRepository.java   |   4 +-
 .../java/mvm/rya/accumulo/AccumuloITBase.java   | 107 +++++
 .../mvm/rya/accumulo/AccumuloRyaITBase.java     | 109 +++++
 .../accumulo/MiniAccumuloClusterInstance.java   | 119 ++++++
 .../AccumuloRyaDetailsRepositoryIT.java         | 101 ++---
 .../mongodb/instance/MongoDetailsAdapter.java   | 112 +++--
 .../instance/MongoDetailsAdapterTest.java       | 215 ++++++----
 .../instance/MongoRyaDetailsRepositoryIT.java   |  52 +--
 extras/indexing/pom.xml                         |  11 +
 .../api/client/accumulo/AccumuloCommand.java    |  64 +++
 .../accumulo/AccumuloConnectionDetails.java     |  83 ++++
 .../api/client/accumulo/AccumuloCreatePCJ.java  | 185 +++++++++
 .../api/client/accumulo/AccumuloDeletePCJ.java  | 130 ++++++
 .../accumulo/AccumuloGetInstanceDetails.java    |  77 ++++
 .../api/client/accumulo/AccumuloInstall.java    | 217 ++++++++++
 .../client/accumulo/AccumuloInstanceExists.java |  71 ++++
 .../client/accumulo/AccumuloListInstances.java  | 141 +++++++
 .../accumulo/AccumuloRyaClientFactory.java      |  59 +++
 .../api/client/accumulo/FluoClientFactory.java  |  72 ++++
 .../external/PrecomputedJoinIndexer.java        |  18 +-
 .../external/accumulo/AccumuloPcjStorage.java   |  96 -----
 .../accumulo/AccumuloPcjStorageConfig.java      |   1 +
 .../accumulo/AccumuloPcjStorageSupplier.java    |   1 +
 .../external/tupleSet/AccumuloIndexSet.java     | 146 ++++---
 .../rya/indexing/pcj/matching/PCJOptimizer.java | 136 ++++---
 .../rya/sail/config/RyaAccumuloSailConfig.java  |  65 +--
 .../rya/sail/config/RyaAccumuloSailFactory.java |  52 +--
 .../mvm/rya/sail/config/RyaSailFactory.java     |  22 +-
 .../client/accumulo/AccumuloCreatePCJIT.java    | 161 ++++++++
 .../client/accumulo/AccumuloDeletePCJIT.java    | 141 +++++++
 .../accumulo/AccumuloGetInstanceDetailsIT.java  | 142 +++++++
 .../api/client/accumulo/AccumuloInstallIT.java  |  85 ++++
 .../accumulo/AccumuloInstanceExistsIT.java      | 100 +++++
 .../accumulo/AccumuloListInstancesIT.java       |  65 +++
 .../mvm/rya/api/client/accumulo/FluoITBase.java | 313 ++++++++++++++
 .../AccumuloConstantPcjIntegrationTest.java     |   2 +-
 .../external/AccumuloPcjIntegrationTest.java    |  28 +-
 .../indexing/external/PCJOptionalTestIT.java    |   2 +-
 .../external/PcjIntegrationTestingUtil.java     |   7 +-
 .../PrecompJoinOptimizerIntegrationTest.java    |   2 +-
 .../PrecomputedJoinStorageSupplierTest.java     |   2 +-
 .../AccumuloIndexSetColumnVisibilityTest.java   | 406 ++++++++++---------
 .../external/tupleSet/AccumuloIndexSetTest.java |   3 +-
 extras/indexingExample/pom.xml                  |  17 +
 .../src/main/java/EntityDirectExample.java      |  48 ++-
 .../src/main/java/MongoRyaDirectExample.java    |   1 -
 .../src/main/java/RyaClientExample.java         | 286 +++++++++++++
 .../src/main/java/RyaDirectExample.java         |  30 +-
 extras/rya.console/pom.xml                      | 174 ++++++--
 .../java/mvm/rya/console/RyaBannerProvider.java |  69 ----
 .../mvm/rya/console/RyaConsoleCommands.java     | 230 -----------
 .../rya/console/RyaHistoryFileNameProvider.java |  47 ---
 .../java/mvm/rya/console/RyaPromptProvider.java |  47 ---
 .../java/mvm/rya/shell/RyaAdminCommands.java    | 254 ++++++++++++
 .../java/mvm/rya/shell/RyaBannerProvider.java   |  97 +++++
 .../mvm/rya/shell/RyaConnectionCommands.java    | 167 ++++++++
 .../java/mvm/rya/shell/RyaPromptProvider.java   |  62 +++
 .../java/mvm/rya/shell/SharedShellState.java    | 338 +++++++++++++++
 .../mvm/rya/shell/util/ConnectorFactory.java    |  66 +++
 .../java/mvm/rya/shell/util/InstallPrompt.java  | 131 ++++++
 .../rya/shell/util/InstanceNamesFormatter.java  |  77 ++++
 .../java/mvm/rya/shell/util/JLinePrompt.java    | 200 +++++++++
 .../java/mvm/rya/shell/util/PasswordPrompt.java |  71 ++++
 .../mvm/rya/shell/util/RyaDetailsFormatter.java | 117 ++++++
 .../java/mvm/rya/shell/util/SparqlPrompt.java   |  55 +++
 .../rya.console/src/main/resources/LICENSE.txt  |  16 +
 .../META-INF/spring/spring-shell-plugin.xml     |  46 ++-
 .../mvm/rya/shell/RyaAdminCommandsTest.java     | 261 ++++++++++++
 .../mvm/rya/shell/RyaConnectionCommandsIT.java  | 269 ++++++++++++
 .../mvm/rya/shell/RyaPromptProviderTest.java    |  80 ++++
 .../test/java/mvm/rya/shell/RyaShellITBase.java | 103 +++++
 .../mvm/rya/shell/SharedShellStateTest.java     | 167 ++++++++
 .../mvm/rya/shell/util/ConnectorFactoryIT.java  |  57 +++
 .../shell/util/InstanceNamesFormatterTest.java  |  81 ++++
 .../rya/shell/util/RyaDetailsFormatterTest.java | 106 +++++
 .../src/test/resources/RyaShellTest-context.xml |  52 +++
 extras/rya.indexing.pcj/pom.xml                 |  10 +
 .../rya/indexing/pcj/storage/PCJIdFactory.java  |  34 ++
 .../pcj/storage/PrecomputedJoinStorage.java     |  18 +-
 .../storage/accumulo/AccumuloPcjStorage.java    | 202 +++++++++
 .../storage/accumulo/PcjTableNameFactory.java   |  31 +-
 .../pcj/storage/accumulo/PcjTables.java         | 211 +++++-----
 .../storage/accumulo/PcjVarOrderFactory.java    |  14 +
 .../accumulo/ScannerBindingSetIterator.java     |  73 ++++
 .../storage/accumulo/ShiftVarOrderFactory.java  |  17 +
 .../accumulo/PcjTableNameFactoryTest.java       |  54 +++
 .../accumulo/PcjTablesIntegrationTest.java      | 250 ++++++------
 .../accumulo/ShiftVarOrderFactoryTest.java      |  73 ++++
 .../accumulo/accumulo/AccumuloPcjStorageIT.java | 272 +++++++++++++
 .../rya/indexing/pcj/fluo/api/CreatePcj.java    |  96 ++---
 .../rya/indexing/pcj/fluo/api/DeletePcj.java    | 287 +++++++++++++
 .../indexing/pcj/fluo/api/GetPcjMetadata.java   |  43 +-
 .../indexing/pcj/fluo/api/InsertTriples.java    |   2 +
 extras/rya.pcj.fluo/pcj.fluo.app/pom.xml        |  16 +
 .../rya/indexing/pcj/fluo/app/NodeType.java     |  52 ++-
 .../app/export/rya/RyaExportParameters.java     |  16 +
 .../fluo/app/export/rya/RyaResultExporter.java  |  26 +-
 .../export/rya/RyaResultExporterFactory.java    |  12 +-
 .../pcj/fluo/app/query/FluoQueryColumns.java    | 158 ++++++--
 .../fluo/app/query/SparqlFluoQueryBuilder.java  |   7 +-
 extras/rya.pcj.fluo/pcj.fluo.client/pom.xml     |   4 +
 .../fluo/client/command/ListQueriesCommand.java |   7 +-
 .../fluo/client/command/NewQueryCommand.java    |  12 +-
 extras/rya.pcj.fluo/pcj.fluo.demo/pom.xml       |   4 +
 .../rya/indexing/pcj/fluo/demo/DemoDriver.java  |  38 +-
 .../pcj/fluo/demo/FluoAndHistoricPcjsDemo.java  | 105 ++---
 .../apache/rya/indexing/pcj/fluo/ITBase.java    |  63 +--
 .../pcj/fluo/api/CountStatementsIT.java         |  13 +-
 .../indexing/pcj/fluo/api/GetPcjMetadataIT.java |  39 +-
 .../indexing/pcj/fluo/api/GetQueryReportIT.java |  14 +-
 .../indexing/pcj/fluo/api/ListQueryIdsIT.java   |   3 -
 .../fluo/app/query/FluoQueryMetadataDAOIT.java  |   3 +-
 .../pcj/fluo/integration/CreateDeleteIT.java    | 124 ++++++
 .../indexing/pcj/fluo/integration/InputIT.java  |  35 +-
 .../indexing/pcj/fluo/integration/QueryIT.java  |  35 +-
 .../pcj/fluo/integration/RyaExportIT.java       |  89 +---
 .../RyaInputIncrementalUpdateIT.java            |  40 +-
 .../pcj/fluo/visibility/PcjVisibilityIT.java    | 299 ++++----------
 .../rya/rdftriplestore/RdfCloudTripleStore.java |  32 +-
 137 files changed, 9650 insertions(+), 2154 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/pom.xml
----------------------------------------------------------------------
diff --git a/common/rya.api/pom.xml b/common/rya.api/pom.xml
index 7c90521..302d335 100644
--- a/common/rya.api/pom.xml
+++ b/common/rya.api/pom.xml
@@ -71,6 +71,11 @@ under the License.
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/client/CreatePCJ.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/mvm/rya/api/client/CreatePCJ.java 
b/common/rya.api/src/main/java/mvm/rya/api/client/CreatePCJ.java
new file mode 100644
index 0000000..ae22ffe
--- /dev/null
+++ b/common/rya.api/src/main/java/mvm/rya/api/client/CreatePCJ.java
@@ -0,0 +1,40 @@
+/**
+ * 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 mvm.rya.api.client;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+/**
+ * Create a new PCJ within the target instance of Rya.
+ */
+@ParametersAreNonnullByDefault
+public interface CreatePCJ {
+
+    /**
+     * Designate a new PCJ that will be maintained by the target instance of 
Rya.
+     *
+     * @param instanceName - Indicates which Rya instance will create and 
maintain
+     *   the PCJ. (not null)
+     * @param sparql - The SPARQL query that will be maintained. (not null)
+     * @return The ID that was assigned to this newly created PCJ.
+     * @throws InstanceDoesNotExistException No instance of Rya exists for the 
provided name.
+     * @throws RyaClientException Something caused the command to fail.
+     */
+    public String createPCJ(final String instanceName, String sparql) throws 
InstanceDoesNotExistException, RyaClientException;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/client/DeletePCJ.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/mvm/rya/api/client/DeletePCJ.java 
b/common/rya.api/src/main/java/mvm/rya/api/client/DeletePCJ.java
new file mode 100644
index 0000000..92b6b71
--- /dev/null
+++ b/common/rya.api/src/main/java/mvm/rya/api/client/DeletePCJ.java
@@ -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 mvm.rya.api.client;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+/**
+ * Deletes a PCJ from an instance of Rya.
+ */
+@ParametersAreNonnullByDefault
+public interface DeletePCJ {
+
+    /**
+     * Deletes a PCJ from an instance of Rya.
+     *
+     * @param instanceName - Indicates which Rya instance is maintaining the 
PCJ. (not null)
+     * @param pcjId - The ID of the PCJ that will be deleted. (not null)
+     * @throws InstanceDoesNotExistException No instance of Rya exists for the 
provided name.
+     * @throws RyaClientException Something caused the command to fail.
+     */
+    public void deletePCJ(String instanceName, final String pcjId) throws 
InstanceDoesNotExistException, RyaClientException;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/client/GetInstanceDetails.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/mvm/rya/api/client/GetInstanceDetails.java 
b/common/rya.api/src/main/java/mvm/rya/api/client/GetInstanceDetails.java
new file mode 100644
index 0000000..536b5a8
--- /dev/null
+++ b/common/rya.api/src/main/java/mvm/rya/api/client/GetInstanceDetails.java
@@ -0,0 +1,44 @@
+/**
+ * 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 mvm.rya.api.client;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import com.google.common.base.Optional;
+
+import mvm.rya.api.instance.RyaDetails;
+
+/**
+ * Get configuration and maintenance information about a specific instance of 
Rya.
+ */
+@ParametersAreNonnullByDefault
+public interface GetInstanceDetails {
+
+    /**
+     * Get configuration and maintenance information about a specific instance 
of Rya.
+     *
+     * @param instanceName - Indicates which Rya instance to fetch the details 
from. (not null)
+     * @return The {@link RyaDetails} that describe the instance of Rya. If 
this is
+     *   an older version of Rya, then there may not be any details to fetch. 
If
+     *   this is the case, empty is returned.
+     * @throws InstanceDoesNotExistException No instance of Rya exists for the 
provided name.
+     * @throws RyaClientException Something caused the command to fail.
+     */
+    public Optional<RyaDetails> getDetails(final String instanceName) throws 
InstanceDoesNotExistException, RyaClientException;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/client/Install.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/mvm/rya/api/client/Install.java 
b/common/rya.api/src/main/java/mvm/rya/api/client/Install.java
new file mode 100644
index 0000000..28a0dc5
--- /dev/null
+++ b/common/rya.api/src/main/java/mvm/rya/api/client/Install.java
@@ -0,0 +1,268 @@
+/**
+ * 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 mvm.rya.api.client;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Objects;
+
+import javax.annotation.Nullable;
+import javax.annotation.ParametersAreNonnullByDefault;
+import javax.annotation.concurrent.Immutable;
+
+import com.google.common.base.Optional;
+
+/**
+ * Installs a new instance of Rya.
+ */
+@ParametersAreNonnullByDefault
+public interface Install {
+
+    /**
+     * Install a new instance of Rya.
+     *
+     * @param instanceName - Indicates the name of the Rya instance to 
install. (not null)
+     * @param installConfig - Configures how the Rya instance will operate. The
+     *   instance name that is in this variable must match the {@code 
instanceName}. (not null)
+     * @throws DuplicateInstanceNameException A Rya instance already exists 
for the provided name.
+     * @throws RyaClientException Something caused the command to fail.
+     */
+    public void install(final String instanceName, final InstallConfiguration 
installConfig) throws DuplicateInstanceNameException, RyaClientException;
+
+    /**
+     * A Rya instance already exists for the provided name.
+     */
+    public static class DuplicateInstanceNameException extends 
RyaClientException {
+        private static final long serialVersionUID = 1L;
+
+        public DuplicateInstanceNameException(final String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * Configures how an instance of Rya will be configured when it is 
installed.
+     */
+    @Immutable
+    @ParametersAreNonnullByDefault
+    public static class InstallConfiguration {
+
+        private final boolean enableTableHashPrefix;
+        private final boolean enableFreeTextIndex;
+        private final boolean enableGeoIndex;
+        private final boolean enableEntityCentricIndex;
+        private final boolean enableTemporalIndex;
+        private final boolean enablePcjIndex;
+        private final Optional<String> fluoPcjAppName;
+
+        /**
+         * Use a {@link Builder} to create instances of this class.
+         */
+        private InstallConfiguration(
+                final boolean enableTableHashPrefix,
+                final boolean enableFreeTextIndex,
+                final boolean enableGeoIndex,
+                final boolean enableEntityCentricIndex,
+                final boolean enableTemporalIndex,
+                final boolean enablePcjIndex,
+                final Optional<String> fluoPcjAppName) {
+            this.enableTableHashPrefix = requireNonNull(enableTableHashPrefix);
+            this.enableFreeTextIndex = requireNonNull(enableFreeTextIndex);
+            this.enableGeoIndex = requireNonNull(enableGeoIndex);
+            this.enableEntityCentricIndex = 
requireNonNull(enableEntityCentricIndex);
+            this.enableTemporalIndex = requireNonNull(enableTemporalIndex);
+            this.enablePcjIndex = requireNonNull(enablePcjIndex);
+            this.fluoPcjAppName = requireNonNull(fluoPcjAppName);
+        }
+
+        /**
+         * @return Whether or not the installed instance of Rya will include 
table prefix hashing.
+         */
+        public boolean isTableHashPrefixEnabled() {
+            return enableTableHashPrefix;
+        }
+
+        /**
+         * @return Whether or not the installed instance of Rya will maintain 
a Free Text index.
+         */
+        public boolean isFreeTextIndexEnabled() {
+            return enableFreeTextIndex;
+        }
+
+        /**
+         * @return Whether or not the installed instance of Rya will maintain 
a Geospatial index.
+         */
+        public boolean isGeoIndexEnabled() {
+            return enableGeoIndex;
+        }
+
+        /**
+         * @return Whether or not the installed instance of Rya will maintain 
an Entity Centric index.
+         */
+        public boolean isEntityCentrixIndexEnabled() {
+            return enableEntityCentricIndex;
+        }
+
+        /**
+         * @return Whether or not the installed instance of Rya will maintain 
a Temporal index.
+         */
+        public boolean isTemporalIndexEnabled() {
+            return enableTemporalIndex;
+        }
+
+        /**
+         * @return Whether or not the installed instance of Rya will maintain 
a PCJ index.
+         */
+        public boolean isPcjIndexEnabled() {
+            return enablePcjIndex;
+        }
+
+        /**
+         * @return The name of the Fluo application that updates this instance 
of Rya's PCJs.
+         *  Optional because this does not have to be the update paradigm used.
+         */
+        public Optional<String> getFluoPcjAppName() {
+            return fluoPcjAppName;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(
+                    enableTableHashPrefix,
+                    enableFreeTextIndex,
+                    enableGeoIndex,
+                    enableEntityCentricIndex,
+                    enableTemporalIndex,
+                    enablePcjIndex,
+                    fluoPcjAppName);
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if(this == obj) {
+                return true;
+            }
+            if(obj instanceof InstallConfiguration) {
+                final InstallConfiguration config = (InstallConfiguration) obj;
+                return enableTableHashPrefix == config.enableTableHashPrefix &&
+                        enableFreeTextIndex == config.enableFreeTextIndex &&
+                        enableGeoIndex == config.enableGeoIndex &&
+                        enableEntityCentricIndex == 
config.enableEntityCentricIndex &&
+                        enableTemporalIndex == config.enableTemporalIndex &&
+                        enablePcjIndex == config.enablePcjIndex &&
+                        Objects.equals(fluoPcjAppName, config.fluoPcjAppName);
+            }
+            return false;
+        }
+
+        /**
+         * @return An empty instance of {@link Builder}.
+         */
+        public static Builder builder() {
+            return new Builder();
+        }
+
+        /**
+         * Builds instances of {@link InstallConfiguration}.
+         */
+        @ParametersAreNonnullByDefault
+        public static class Builder {
+            private boolean enableTableHashPrefix = false;
+            private boolean enableFreeTextIndex = false;
+            private boolean enableGeoIndex = false;
+            private boolean enableEntityCentricIndex = false;
+            private boolean enableTemporalIndex = false;
+            private boolean enablePcjIndex = false;
+            private String fluoPcjAppName = null;
+
+            /**
+             * @param enabled - Whether or not the installed instance of Rya 
will include table prefix hashing.
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder setEnableTableHashPrefix(final boolean enabled) {
+                enableTableHashPrefix = enabled;
+                return this;
+            }
+
+            /**
+             * @param enabled - Whether or not the installed instance of Rya 
will maintain a Free Text index.
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder setEnableFreeTextIndex(final boolean enabled) {
+                enableFreeTextIndex = enabled;
+                return this;
+            }
+
+            /**
+             * @param enabled - Whether or not the installed instance of Rya 
will maintain a Geospatial index.
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder setEnableGeoIndex(final boolean enabled) {
+                enableGeoIndex = enabled;
+                return this;
+            }
+
+            /**
+             * @param enabled - Whether or not the installed instance of Rya 
will maintain an Entity Centric index.
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder setEnableEntityCentricIndex(final boolean enabled) {
+                enableEntityCentricIndex = enabled;
+                return this;
+            }
+
+            /**
+             * @param enabled - Whether or not the installed instance of Rya 
will maintain a Temporal index.
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder setEnableTemporalIndex(final boolean enabled) {
+                enableTemporalIndex = enabled;
+                return this;
+            }
+
+            /**
+             * @param enabled - Whether or not the installed instance of Rya 
will maintain a PCJ index.
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder setEnablePcjIndex(final boolean enabled) {
+                enablePcjIndex = enabled;
+                return this;
+            }
+
+            public Builder setFluoPcjAppName(@Nullable final String 
fluoPcjAppName) {
+                this.fluoPcjAppName = fluoPcjAppName;
+                return this;
+            }
+
+            /**
+             * @return Builds an instance of {@link InstallConfiguration} 
using this builder's values.
+             */
+            public InstallConfiguration build() {
+                return new InstallConfiguration(
+                        enableTableHashPrefix,
+                        enableFreeTextIndex,
+                        enableGeoIndex,
+                        enableEntityCentricIndex,
+                        enableTemporalIndex,
+                        enablePcjIndex,
+                        Optional.fromNullable(fluoPcjAppName));
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/client/InstanceDoesNotExistException.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/mvm/rya/api/client/InstanceDoesNotExistException.java
 
b/common/rya.api/src/main/java/mvm/rya/api/client/InstanceDoesNotExistException.java
new file mode 100644
index 0000000..c8cc0aa
--- /dev/null
+++ 
b/common/rya.api/src/main/java/mvm/rya/api/client/InstanceDoesNotExistException.java
@@ -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 mvm.rya.api.client;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+/**
+ * One of the {@link RyaClient} commands could not execute because the 
connected
+ * instance of Rya does not exist.
+ */
+@ParametersAreNonnullByDefault
+public class InstanceDoesNotExistException extends RyaClientException {
+    private static final long serialVersionUID = 1L;
+
+    public InstanceDoesNotExistException(final String message) {
+        super(message);
+    }
+
+    public InstanceDoesNotExistException(final String message, final Throwable 
cause) {
+        super(message, cause);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/client/InstanceExists.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/mvm/rya/api/client/InstanceExists.java 
b/common/rya.api/src/main/java/mvm/rya/api/client/InstanceExists.java
new file mode 100644
index 0000000..6f26fc6
--- /dev/null
+++ b/common/rya.api/src/main/java/mvm/rya/api/client/InstanceExists.java
@@ -0,0 +1,37 @@
+/**
+ * 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 mvm.rya.api.client;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+/**
+ * Checks if an instance of Rya has been installed.
+ */
+@ParametersAreNonnullByDefault
+public interface InstanceExists {
+
+    /**
+     * Checks if an instance of Rya has been installed.
+     *
+     * @param instanceName - The name to check. (not null)
+     * @return {@code true} If an instance of Rya exists with the provided 
name; otherwise {@code false}.
+     * @throws RyaClientException Something caused the command to fail.
+     */
+    public boolean exists(String instanceName) throws RyaClientException;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/client/ListInstances.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/mvm/rya/api/client/ListInstances.java 
b/common/rya.api/src/main/java/mvm/rya/api/client/ListInstances.java
new file mode 100644
index 0000000..5edfbc4
--- /dev/null
+++ b/common/rya.api/src/main/java/mvm/rya/api/client/ListInstances.java
@@ -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 mvm.rya.api.client;
+
+import java.util.List;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+/**
+ * List the names of the installed Rya instances.
+ */
+@ParametersAreNonnullByDefault
+public interface ListInstances {
+
+    /**
+     * List the names of the installed Rya instances.
+     *
+     * @return The names of the installed Rya Instances.
+     * @throws RyaClientException Something caused the command to fail.
+     */
+    public List<String> listInstances() throws RyaClientException;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/client/RyaClient.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/mvm/rya/api/client/RyaClient.java 
b/common/rya.api/src/main/java/mvm/rya/api/client/RyaClient.java
new file mode 100644
index 0000000..173e1e0
--- /dev/null
+++ b/common/rya.api/src/main/java/mvm/rya/api/client/RyaClient.java
@@ -0,0 +1,101 @@
+/**
+ * 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 mvm.rya.api.client;
+
+import static java.util.Objects.requireNonNull;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * Provides access to a set of Rya functions.
+ */
+@Immutable
+@ParametersAreNonnullByDefault
+public class RyaClient {
+    // Administrative functions.
+    private final Install install;
+    private final CreatePCJ createPcj;
+    private final DeletePCJ deletePcj;
+    private final GetInstanceDetails getInstanceDetails;
+    private final InstanceExists instanceExists;
+    private final ListInstances listInstances;
+
+    /**
+     * Constructs an isntance of {@link RyaClient}.
+     */
+    public RyaClient(
+            final Install install,
+            final CreatePCJ createPcj,
+            final DeletePCJ deletePcj,
+            final GetInstanceDetails getInstanceDetails,
+            final InstanceExists instanceExists,
+            final ListInstances listInstances) {
+        this.install = requireNonNull(install);
+        this.createPcj = requireNonNull(createPcj);
+        this.deletePcj = requireNonNull(deletePcj);
+        this.getInstanceDetails = requireNonNull(getInstanceDetails);
+        this.instanceExists = requireNonNull(instanceExists);
+        this.listInstances = requireNonNull(listInstances);
+    }
+
+    /**
+     * @return An instance of {@link Install} that is connected to a Rya 
storage.
+     */
+    public Install getInstall() {
+        return install;
+    }
+
+    /**
+     * @return An instance of {@link CreatePCJ} that is connected to a Rya 
storage
+     *   if the Rya instance supports PCJ indexing.
+     */
+    public CreatePCJ getCreatePCJ() {
+        return createPcj;
+    }
+
+    /**
+     * @return An instance of {@link DeletePCJ} that is connected to a Rya 
storage
+     *   if the Rya instance supports PCJ indexing.
+     */
+    public DeletePCJ getDeletePCJ() {
+        return deletePcj;
+    }
+
+    /**
+     * @return An instance of {@link GetInstanceDetails} that is connected to 
a Rya storage.
+     */
+    public GetInstanceDetails getGetInstanceDetails() {
+        return getInstanceDetails;
+    }
+
+    /**
+     * @return An instance of {@link ListInstances} that is connected to a Rya 
storage.
+     */
+    public ListInstances getListInstances() {
+        return listInstances;
+    }
+
+    /**
+     * @return An instance of {@link InstanceExists} that is connected to a 
Rya storage.
+     */
+    public InstanceExists getInstanceExists() {
+        return instanceExists;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/client/RyaClientException.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/mvm/rya/api/client/RyaClientException.java 
b/common/rya.api/src/main/java/mvm/rya/api/client/RyaClientException.java
new file mode 100644
index 0000000..28c78aa
--- /dev/null
+++ b/common/rya.api/src/main/java/mvm/rya/api/client/RyaClientException.java
@@ -0,0 +1,37 @@
+/**
+ * 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 mvm.rya.api.client;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+/**
+ * One of the {@link RyaClient} functions failed.
+ */
+@ParametersAreNonnullByDefault
+public class RyaClientException extends Exception {
+    private static final long serialVersionUID = 1L;
+
+    public RyaClientException(final String message) {
+        super(message);
+    }
+
+    public RyaClientException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetails.java
----------------------------------------------------------------------
diff --git a/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetails.java 
b/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetails.java
index 91d6608..565b545 100644
--- a/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetails.java
+++ b/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetails.java
@@ -23,6 +23,9 @@ import static java.util.Objects.requireNonNull;
 
 import java.io.Serializable;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Objects;
 
 import javax.annotation.Nullable;
@@ -186,6 +189,14 @@ public class RyaDetails implements Serializable {
     }
 
     /**
+     * @param detials - The builder will be initialized with this object's 
values. (not null)
+     * @return An instance of {@link Builder} that is initialized with a 
{@link RyaDetails}'s values.
+     */
+    public static Builder builder(final RyaDetails details) {
+        return new Builder(details);
+    }
+
+    /**
      * Builds instances of {@link RyaDetails}.
      */
     @ParametersAreNonnullByDefault
@@ -198,7 +209,7 @@ public class RyaDetails implements Serializable {
         // Secondary Index Details.
         private EntityCentricIndexDetails entityCentricDetails;
         private GeoIndexDetails geoDetails;
-        private PCJIndexDetails pcjDetails;
+        private PCJIndexDetails.Builder pcjIndexDetailsBuilder;
         private TemporalIndexDetails temporalDetails;
         private FreeTextIndexDetails freeTextDetails;
 
@@ -219,12 +230,11 @@ public class RyaDetails implements Serializable {
          */
         public Builder(final RyaDetails details) {
             requireNonNull(details);
-
             instanceName = details.instanceName;
             version = details.version;
             entityCentricDetails = details.entityCentricDetails;
             geoDetails = details.geoDetails;
-            pcjDetails = details.pcjDetails;
+            pcjIndexDetailsBuilder = PCJIndexDetails.builder( 
details.pcjDetails );
             temporalDetails = details.temporalDetails;
             freeTextDetails = details.freeTextDetails;
             prospectorDetails = details.prospectorDetails;
@@ -291,12 +301,20 @@ public class RyaDetails implements Serializable {
          * @param pcjDetails - Information about the instance's Precomputed 
Join Index.
          * @return This {@link Builder} so that method invocations may be 
chained.
          */
-        public Builder setPCJIndexDetails(@Nullable final PCJIndexDetails 
pcjDetails) {
-            this.pcjDetails = pcjDetails;
+        public Builder setPCJIndexDetails(@Nullable final 
PCJIndexDetails.Builder pcjDetailsBuilder) {
+            this.pcjIndexDetailsBuilder = pcjDetailsBuilder;
             return this;
         }
 
         /**
+         * @return Get the {@link PCJIndexDetails.Builder} used to build the
+         *   PCJ Index's details.
+         */
+        public @Nullable PCJIndexDetails.Builder getPCJIndexDetails() {
+            return pcjIndexDetailsBuilder;
+        }
+
+        /**
          * @param prospectorDetails - Information about the instance's 
Prospector Statistics.
          * @return This {@link Builder} so that method invocations may be 
chained.
          */
@@ -324,7 +342,7 @@ public class RyaDetails implements Serializable {
                     version,
                     entityCentricDetails,
                     geoDetails,
-                    pcjDetails,
+                    pcjIndexDetailsBuilder.build(),
                     temporalDetails,
                     freeTextDetails,
                     prospectorDetails,
@@ -590,6 +608,14 @@ public class RyaDetails implements Serializable {
         }
 
         /**
+         * @param detials - The builder will be initialized with this object's 
values. (not null)
+         * @return An instance of {@link Builder} that is initialized with a 
{@link PCJIndexDetails}'s values.
+         */
+        public static Builder builder(final PCJIndexDetails pcjIndexDetails) {
+            return new Builder(pcjIndexDetails);
+        }
+
+        /**
          * Builds instance of {@link PCJIndexDetails).
          */
         @ParametersAreNonnullByDefault
@@ -597,7 +623,29 @@ public class RyaDetails implements Serializable {
 
             private Boolean enabled = null;
             private FluoDetails fluoDetails = null;
-            private final ImmutableMap.Builder<String, PCJDetails> pcjDetails 
= ImmutableMap.builder();
+            private final Map<String, PCJDetails.Builder> pcjDetailsBuilders = 
new HashMap<>();
+
+            /**
+             * Constructs an empty instance of {@link Builder}.
+             */
+            public Builder() { }
+
+            /**
+             * Constructs an instance of {@link Builder} that is initialized 
with
+             * the values of a {@link PCJIndexDetails}.
+             *
+             * @param pcjIndexDetails - This objects values will be used to 
initialize
+             *   the builder. (not null)
+             */
+            public Builder(final PCJIndexDetails pcjIndexDetails) {
+                requireNonNull(pcjIndexDetails);
+                this.enabled = pcjIndexDetails.enabled;
+                this.fluoDetails = pcjIndexDetails.fluoDetails.orNull();
+
+                for(final PCJDetails pcjDetails : 
pcjIndexDetails.pcjDetails.values()) {
+                    pcjDetailsBuilders.put(pcjDetails.getId(), 
PCJDetails.builder(pcjDetails));
+                }
+            }
 
             /**
              * @param enabled - Whether or not a Precomputed Join Index will 
be maintained by the Rya instance.
@@ -622,17 +670,32 @@ public class RyaDetails implements Serializable {
              * @param pcjDetails - Details about the PCJs that have been 
created for this Rya instance.
              * @return This {@link Builder} so that method invocations may be 
chained.
              */
-            public Builder addPCJDetails(@Nullable final PCJDetails 
pcjDetails) {
-                if(pcjDetails != null) {
-                    this.pcjDetails.put(pcjDetails.getId(), pcjDetails);
+            public Builder addPCJDetails(@Nullable final PCJDetails.Builder 
pcjDetailsBuilder) {
+                if(pcjDetailsBuilder != null) {
+                    this.pcjDetailsBuilders.put(pcjDetailsBuilder.getId(), 
pcjDetailsBuilder);
                 }
                 return this;
             }
 
             /**
+             * @param pcjId - The PCJ ID of the {@link PCJDetails.Builder} to 
remove. (not null)
+             * @return This {@link Builder} so that method invocations may be 
chained.
+             */
+            public Builder removePCJDetails(@Nullable final String pcjId) {
+                requireNonNull(pcjId);
+                this.pcjDetailsBuilders.remove(pcjId);
+                return this;
+            }
+
+            /**
              * @return Builds an instance of {@link PCJIndexDetails} using 
this builder's values.
              */
             public PCJIndexDetails build() {
+                final ImmutableMap.Builder<String, PCJDetails> pcjDetails = 
ImmutableMap.builder();
+                for(final Entry<String, PCJDetails.Builder> entry : 
pcjDetailsBuilders.entrySet()) {
+                    pcjDetails.put(entry.getKey(), entry.getValue().build());
+                }
+
                 return new PCJIndexDetails(
                         enabled,
                         Optional.fromNullable( fluoDetails ),
@@ -695,7 +758,7 @@ public class RyaDetails implements Serializable {
             private static final long serialVersionUID = 1L;
 
             private final String id;
-            private final PCJUpdateStrategy updateStrategy;
+            private final Optional<PCJUpdateStrategy> updateStrategy;
             private final Optional<Date> lastUpdateTime;
 
             /**
@@ -709,7 +772,7 @@ public class RyaDetails implements Serializable {
              */
             private PCJDetails(
                     final String id,
-                    final PCJUpdateStrategy updateStrategy,
+                    final Optional<PCJUpdateStrategy> updateStrategy,
                     final Optional<Date> lastUpdateTime) {
                 this.id = requireNonNull(id);
                 this.updateStrategy = requireNonNull(updateStrategy);
@@ -726,7 +789,7 @@ public class RyaDetails implements Serializable {
             /**
              * @return Describes how the PCJ is being updated.
              */
-            public PCJUpdateStrategy getUpdateStrategy() {
+            public Optional<PCJUpdateStrategy> getUpdateStrategy() {
                 return updateStrategy;
             }
 
@@ -765,6 +828,14 @@ public class RyaDetails implements Serializable {
             }
 
             /**
+             * @param detials - The builder will be initialized with this 
object's values. (not null)
+             * @return An instance of {@link Builder} that is initialized with 
a {@link PCJDetails}' values.
+             */
+            public static Builder builder(final PCJDetails details) {
+                return new Builder(details);
+            }
+
+            /**
              * Builds instance of {@link PCJDetails}.
              */
             @ParametersAreNonnullByDefault
@@ -775,6 +846,31 @@ public class RyaDetails implements Serializable {
                 private Date lastUpdateTime;
 
                 /**
+                 * Constructs an instance of {@link Builder}.
+                 */
+                public Builder() { }
+
+                /**
+                 * Constructs an instance of {@link Builder} that is 
initialized with
+                 * the values of a {@link PCJDetails}.
+                 *
+                 * @param details - This object's values will be used to 
initialize the builder. (not null)
+                 */
+                public Builder(final PCJDetails details) {
+                    requireNonNull(details);
+                    this.id = details.id;
+                    this.updateStrategy = details.updateStrategy.orNull();
+                    this.lastUpdateTime = details.lastUpdateTime.orNull();
+                }
+
+                /**
+                 * @return Uniquely identifies the PCJ within this instance of 
Rya.
+                 */
+                public @Nullable String getId() {
+                    return id;
+                }
+
+                /**
                  * @param id - Uniquely identifies the PCJ within this 
instance of Rya.
                  * @return This {@link Builder} so that method invocations may 
be chained.
                  */
@@ -784,6 +880,13 @@ public class RyaDetails implements Serializable {
                 }
 
                 /**
+                 * @return Describes how the PCJ is being updated.
+                 */
+                public PCJUpdateStrategy getUpdateStrategy() {
+                    return updateStrategy;
+                }
+
+                /**
                  * @param updateStrategy - Describes how the PCJ is being 
updated.
                  * @return This {@link Builder} so that method invocations may 
be chained.
                  */
@@ -793,6 +896,13 @@ public class RyaDetails implements Serializable {
                 }
 
                 /**
+                 * @return The last time the PCJ was updated. This information 
may not be provided.
+                 */
+                public @Nullable Date getLastUpdateTime() {
+                    return lastUpdateTime;
+                }
+
+                /**
                  * @param lastUpdateTime - The last time the PCJ was updated. 
This information
                  *   may not be provided.
                  * @return This {@link Builder} so that method invocations may 
be chained.
@@ -806,7 +916,10 @@ public class RyaDetails implements Serializable {
                  * @return An instance of {@link PCJDetails} built using this 
builder's values.
                  */
                 public PCJDetails build() {
-                    return new PCJDetails(id, updateStrategy, 
Optional.fromNullable(lastUpdateTime));
+                    return new PCJDetails(
+                            id,
+                            Optional.fromNullable(updateStrategy),
+                            Optional.fromNullable(lastUpdateTime));
                 }
             }
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetailsToConfiguration.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetailsToConfiguration.java
 
b/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetailsToConfiguration.java
index 75ae416..faec0ff 100644
--- 
a/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetailsToConfiguration.java
+++ 
b/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetailsToConfiguration.java
@@ -1,4 +1,4 @@
-/*
+/**
  * 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
@@ -7,7 +7,7 @@
  * "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
+ *     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

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetailsUpdater.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetailsUpdater.java 
b/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetailsUpdater.java
new file mode 100644
index 0000000..9d5dae7
--- /dev/null
+++ b/common/rya.api/src/main/java/mvm/rya/api/instance/RyaDetailsUpdater.java
@@ -0,0 +1,124 @@
+/**
+ * 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 mvm.rya.api.instance;
+
+import static java.util.Objects.requireNonNull;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import mvm.rya.api.instance.RyaDetailsRepository.ConcurrentUpdateException;
+import mvm.rya.api.instance.RyaDetailsRepository.RyaDetailsRepositoryException;
+import 
mvm.rya.api.instance.RyaDetailsUpdater.RyaDetailsMutator.CouldNotApplyMutationException;
+
+/**
+ * A utility that will attempt to commit a change to a Rya instance's details
+ * until it either takes or the mutation can no longer be applied. This can
+ * can be used in place of boilerplate code that handles the concurrent nature
+ * of details updates.
+ */
+@ParametersAreNonnullByDefault
+public class RyaDetailsUpdater {
+    private static final Logger log = 
LoggerFactory.getLogger(RyaDetailsUpdater.class);
+
+    /**
+     * Applies a mutation to a an instance of {@link RyaDetails}.
+     */
+    @ParametersAreNonnullByDefault
+    public static interface RyaDetailsMutator {
+
+        /**
+         * Applies a mutation to a {@link RyaDetails} object.
+         *
+         * @param originalDetails - The {@link RyaDetails} that were just 
fetched
+         *   from the {@link RyaDetailsRepository}.
+         * @return The updated details.
+         * @throws CouldNotApplyMutationException The mutation could not be 
applied
+         *   to the supplied {@link RyaDetails}. This can be used to break out 
of
+         *   the update loop when the details are in a state the mutation can 
not
+         *   be applied to.
+         */
+        public RyaDetails mutate(RyaDetails originalDetails) throws 
CouldNotApplyMutationException;
+
+        /**
+         * Indicates a mutation could not be applied to an instance of {@link 
RyaDetails}.
+         */
+        public static class CouldNotApplyMutationException extends Exception {
+            private static final long serialVersionUID = 1L;
+
+            /**
+             * Constructs a new exception with the specified detail message.  
The
+             * cause is not initialized, and may subsequently be initialized by
+             * a call to {@link #initCause(Throwable)}.
+             *
+             * @param   message   the detail message. The detail message is 
saved for
+             *          later retrieval by the {@link #getMessage()} method.
+             */
+            public CouldNotApplyMutationException(final String message) {
+                super(message);
+            }
+        }
+    }
+
+    private final RyaDetailsRepository repo;
+
+    /**
+     * Constructs an instance of {@link RyaDetailsUpdater}.
+     *
+     * @param repo - The repository that this updater will commit changes to. 
(not null)
+     */
+    public RyaDetailsUpdater(final RyaDetailsRepository repo) {
+        this.repo = requireNonNull(repo);
+    }
+
+    /**
+     * Updates an instance of {@link RyaDetails} by fetching the details from
+     * the {@link RyaDetailsRepository} that was supplied at construction time,
+     * applying the {@link RyaDetailsMutator} to them, and them committing the
+     * change. If the update failed because of a concurrent update problem, 
then
+     * it will try again. The updater will continue to do this until the 
changes
+     * take or another exception type is thrown.
+     *
+     * @param mutator - The mutator that will be used to apply a chagne to the
+     *   repository's {@link RyaDetails}.
+     * @throws RyaDetailsRepositoryException A repository side error caused
+     *   the update to fail. This could be a communications problem with the
+     *   store repository, uninitialized, etc.
+     * @throws CouldNotApplyMutationException An application side error caused
+     *   the update to fail. This is thrown by the mutator when the details
+     *   would be in an illegal state if the mutation were to be applied.
+     */
+    public void update(final RyaDetailsMutator mutator) throws 
RyaDetailsRepositoryException, CouldNotApplyMutationException {
+        requireNonNull(mutator);
+
+        boolean updated = false;
+        while(!updated) {
+            try {
+                final RyaDetails original = repo.getRyaInstanceDetails();
+                final RyaDetails mutated = mutator.mutate(original);
+                repo.update(original, mutated);
+                updated = true;
+            } catch(final ConcurrentUpdateException e) {
+                log.debug("Failed to update the details because another 
application changed them. Trying again.", e);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsTest.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsTest.java 
b/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsTest.java
index c629fb6..c613fee 100644
--- a/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsTest.java
+++ b/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsTest.java
@@ -61,14 +61,11 @@ public class RyaDetailsTest {
                                 PCJDetails.builder()
                                     .setId("pcj 1")
                                     .setUpdateStrategy(PCJUpdateStrategy.BATCH)
-                                    .setLastUpdateTime( new Date() )
-                                    .build())
+                                    .setLastUpdateTime( new Date() ))
                         .addPCJDetails(
                                 PCJDetails.builder()
                                     .setId("pcj 2")
-                                    
.setUpdateStrategy(PCJUpdateStrategy.INCREMENTAL)
-                                    .build())
-                        .build())
+                                    
.setUpdateStrategy(PCJUpdateStrategy.INCREMENTAL)))
             .setProspectorDetails( new ProspectorDetails(Optional.of(new 
Date())) )
             .setJoinSelectivityDetails( new 
JoinSelectivityDetails(Optional.of(new Date())) );
 
@@ -95,14 +92,11 @@ public class RyaDetailsTest {
                                 PCJDetails.builder()
                                     .setId("pcj 1")
                                     .setUpdateStrategy(PCJUpdateStrategy.BATCH)
-                                    .setLastUpdateTime( new Date() )
-                                    .build())
+                                    .setLastUpdateTime( new Date() ))
                         .addPCJDetails(
                                 PCJDetails.builder()
                                     .setId("pcj 2")
-                                    
.setUpdateStrategy(PCJUpdateStrategy.INCREMENTAL)
-                                    .build())
-                        .build())
+                                    
.setUpdateStrategy(PCJUpdateStrategy.INCREMENTAL)))
             .setProspectorDetails( new ProspectorDetails(Optional.of(new 
Date())) )
             .setJoinSelectivityDetails( new 
JoinSelectivityDetails(Optional.of(new Date())) );
 
@@ -128,14 +122,11 @@ public class RyaDetailsTest {
                                 PCJDetails.builder()
                                     .setId("pcj 1")
                                     .setUpdateStrategy(PCJUpdateStrategy.BATCH)
-                                    .setLastUpdateTime( new Date() )
-                                    .build())
+                                    .setLastUpdateTime( new Date() ))
                         .addPCJDetails(
                                 PCJDetails.builder()
                                     .setId("pcj 2")
-                                    
.setUpdateStrategy(PCJUpdateStrategy.INCREMENTAL)
-                                    .build())
-                        .build())
+                                    
.setUpdateStrategy(PCJUpdateStrategy.INCREMENTAL)))
             .setProspectorDetails( new ProspectorDetails(Optional.of(new 
Date())) )
             .setJoinSelectivityDetails( new 
JoinSelectivityDetails(Optional.of(new Date())) )
             .build();

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsToConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsToConfigurationTest.java
 
b/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsToConfigurationTest.java
index 32b75cf..960e8a9 100644
--- 
a/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsToConfigurationTest.java
+++ 
b/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsToConfigurationTest.java
@@ -64,14 +64,11 @@ public class RyaDetailsToConfigurationTest {
                                 PCJDetails.builder()
                                     .setId("pcj 1")
                                     .setUpdateStrategy(PCJUpdateStrategy.BATCH)
-                                    .setLastUpdateTime( new Date() )
-                                    .build())
+                                    .setLastUpdateTime( new Date() ))
                         .addPCJDetails(
                                 PCJDetails.builder()
                                     .setId("pcj 2")
-                                    
.setUpdateStrategy(PCJUpdateStrategy.INCREMENTAL)
-                                    .build())
-                        .build())
+                                    
.setUpdateStrategy(PCJUpdateStrategy.INCREMENTAL)))
             .setProspectorDetails( new ProspectorDetails(Optional.of(new 
Date())) )
             .setJoinSelectivityDetails( new 
JoinSelectivityDetails(Optional.of(new Date())) );
         final Configuration conf = new Configuration();

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsUpdaterTest.java
----------------------------------------------------------------------
diff --git 
a/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsUpdaterTest.java 
b/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsUpdaterTest.java
new file mode 100644
index 0000000..596cc7b
--- /dev/null
+++ 
b/common/rya.api/src/test/java/mvm/rya/api/instance/RyaDetailsUpdaterTest.java
@@ -0,0 +1,141 @@
+/**
+ * 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 mvm.rya.api.instance;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Date;
+
+import org.junit.Test;
+
+import com.google.common.base.Optional;
+
+import mvm.rya.api.instance.RyaDetails.EntityCentricIndexDetails;
+import mvm.rya.api.instance.RyaDetails.FreeTextIndexDetails;
+import mvm.rya.api.instance.RyaDetails.GeoIndexDetails;
+import mvm.rya.api.instance.RyaDetails.JoinSelectivityDetails;
+import mvm.rya.api.instance.RyaDetails.PCJIndexDetails;
+import mvm.rya.api.instance.RyaDetails.ProspectorDetails;
+import mvm.rya.api.instance.RyaDetails.TemporalIndexDetails;
+import mvm.rya.api.instance.RyaDetailsRepository.ConcurrentUpdateException;
+import mvm.rya.api.instance.RyaDetailsRepository.NotInitializedException;
+import mvm.rya.api.instance.RyaDetailsRepository.RyaDetailsRepositoryException;
+import mvm.rya.api.instance.RyaDetailsUpdater.RyaDetailsMutator;
+import 
mvm.rya.api.instance.RyaDetailsUpdater.RyaDetailsMutator.CouldNotApplyMutationException;
+
+/**
+ * Tests the methods of {@link RyaDetailsUpdater}.
+ */
+public class RyaDetailsUpdaterTest {
+
+    @Test
+    public void update() throws RyaDetailsRepositoryException, 
CouldNotApplyMutationException {
+        // Setup initial details and mock a repository that returns them.
+        final RyaDetails originalDetails = RyaDetails.builder()
+                .setRyaInstanceName("instanceName")
+                .setRyaVersion("0.0.0.0")
+                .setFreeTextDetails( new FreeTextIndexDetails(true) )
+                .setEntityCentricIndexDetails( new 
EntityCentricIndexDetails(true) )
+                .setGeoIndexDetails( new GeoIndexDetails(true) )
+                .setTemporalIndexDetails( new TemporalIndexDetails(true) )
+                .setPCJIndexDetails(
+                        PCJIndexDetails.builder()
+                            .setEnabled(true) )
+                .setJoinSelectivityDetails( new JoinSelectivityDetails( 
Optional.<Date>absent() ) )
+                .setProspectorDetails( new ProspectorDetails( 
Optional.<Date>absent() ))
+                .build();
+
+        final RyaDetailsRepository detailsRepo = mock( 
RyaDetailsRepository.class );
+        when( detailsRepo.getRyaInstanceDetails() ).thenReturn( 
originalDetails );
+
+        // Use an updater to change the Rya version number.
+        new RyaDetailsUpdater(detailsRepo).update(new RyaDetailsMutator() {
+            @Override
+            public RyaDetails mutate(final RyaDetails old) {
+                return RyaDetails.builder(old)
+                        .setRyaVersion("1.1.1.1")
+                        .build();
+            }
+        });
+
+        // Verify the repository was asked to update the details.
+        final RyaDetails mutatedDetails = RyaDetails.builder(originalDetails)
+                .setRyaVersion("1.1.1.1")
+                .build();
+        verify(detailsRepo, times(1)).update( eq(originalDetails), 
eq(mutatedDetails) );
+    }
+
+    @Test
+    public void update_concurrentUpdateEncountered() throws 
NotInitializedException, RyaDetailsRepositoryException, 
CouldNotApplyMutationException {
+        // Setup initial details and mock a repository that returns them.
+        final RyaDetails originalDetails = RyaDetails.builder()
+                .setRyaInstanceName("instanceName")
+                .setRyaVersion("0.0.0.0")
+                .setFreeTextDetails( new FreeTextIndexDetails(true) )
+                .setEntityCentricIndexDetails( new 
EntityCentricIndexDetails(true) )
+                .setGeoIndexDetails( new GeoIndexDetails(true) )
+                .setTemporalIndexDetails( new TemporalIndexDetails(true) )
+                .setPCJIndexDetails(
+                        PCJIndexDetails.builder()
+                            .setEnabled(true) )
+                .setJoinSelectivityDetails( new JoinSelectivityDetails( 
Optional.<Date>absent() ) )
+                .setProspectorDetails( new ProspectorDetails( 
Optional.<Date>absent() ))
+                .build();
+
+        final RyaDetails otherUsersUpdate = RyaDetails.builder(originalDetails)
+                .setRyaVersion("1.1.1.1")
+                .build();
+
+        // The first time get detail is called, we get the original state for 
the details.
+        // When the mutator tries to update using those, it throws an 
exception.
+        // The second iteration, the other user's state is updated.
+        // When the mutator tries to update again, it succeeds.
+        final RyaDetailsRepository detailsRepo = mock( 
RyaDetailsRepository.class );
+
+        when( detailsRepo.getRyaInstanceDetails() )
+            .thenReturn( originalDetails )
+            .thenReturn( otherUsersUpdate );
+
+        doThrow( ConcurrentUpdateException.class ).when( detailsRepo ).update( 
eq(originalDetails), any(RyaDetails.class) );
+
+        // Run the test.
+        new RyaDetailsUpdater(detailsRepo).update(new RyaDetailsMutator() {
+            @Override
+            public RyaDetails mutate(final RyaDetails old) {
+                return RyaDetails.builder(old)
+                        .setTemporalIndexDetails( new 
TemporalIndexDetails(false) )
+                        .build();
+            }
+        });
+
+        // Verify the intended mutation eventually gets committed.
+        final RyaDetails finalDetails = RyaDetails.builder(originalDetails)
+                .setRyaVersion("1.1.1.1")
+                .setTemporalIndexDetails( new TemporalIndexDetails(false) )
+                .build();
+
+        verify(detailsRepo, times(1)).update( eq(otherUsersUpdate), 
eq(finalDetails) );
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/dao/accumulo.rya/pom.xml
----------------------------------------------------------------------
diff --git a/dao/accumulo.rya/pom.xml b/dao/accumulo.rya/pom.xml
index 1fa6f55..b837fa3 100644
--- a/dao/accumulo.rya/pom.xml
+++ b/dao/accumulo.rya/pom.xml
@@ -84,6 +84,20 @@ under the License.
     <build>
         <plugins>
             <plugin>
+                <!--  generate the test jar as well so it can be reused by 
dependent tools.
+                TODO this is messy.  in the future, classes that provide this 
functionality 
+                should be decoupled into reusable frameworks. -->
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        
+            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-failsafe-plugin</artifactId>
                 <executions>

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/AccumuloRyaDAO.java
----------------------------------------------------------------------
diff --git 
a/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/AccumuloRyaDAO.java 
b/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/AccumuloRyaDAO.java
index ed991e1..195030e 100644
--- a/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/AccumuloRyaDAO.java
+++ b/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/AccumuloRyaDAO.java
@@ -31,7 +31,6 @@ import static 
mvm.rya.api.RdfCloudTripleStoreConstants.NUM_THREADS;
 import static mvm.rya.api.RdfCloudTripleStoreConstants.RTS_SUBJECT_RYA;
 import static 
mvm.rya.api.RdfCloudTripleStoreConstants.RTS_VERSION_PREDICATE_RYA;
 import static mvm.rya.api.RdfCloudTripleStoreConstants.VERSION_RYA;
-import info.aduna.iteration.CloseableIteration;
 
 import java.io.IOException;
 import java.util.Collection;
@@ -41,18 +40,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
-import mvm.rya.accumulo.experimental.AccumuloIndexer;
-import mvm.rya.accumulo.query.AccumuloRyaQueryEngine;
-import mvm.rya.api.RdfCloudTripleStoreConfiguration;
-import mvm.rya.api.RdfCloudTripleStoreConstants.TABLE_LAYOUT;
-import mvm.rya.api.domain.RyaStatement;
-import mvm.rya.api.domain.RyaURI;
-import mvm.rya.api.layout.TableLayoutStrategy;
-import mvm.rya.api.persist.RyaDAO;
-import mvm.rya.api.persist.RyaDAOException;
-import mvm.rya.api.persist.RyaNamespaceManager;
-import mvm.rya.api.resolver.RyaTripleContext;
-
 import org.apache.accumulo.core.client.AccumuloException;
 import org.apache.accumulo.core.client.AccumuloSecurityException;
 import org.apache.accumulo.core.client.BatchDeleter;
@@ -77,6 +64,19 @@ import org.openrdf.model.Namespace;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
 
+import info.aduna.iteration.CloseableIteration;
+import mvm.rya.accumulo.experimental.AccumuloIndexer;
+import mvm.rya.accumulo.query.AccumuloRyaQueryEngine;
+import mvm.rya.api.RdfCloudTripleStoreConfiguration;
+import mvm.rya.api.RdfCloudTripleStoreConstants.TABLE_LAYOUT;
+import mvm.rya.api.domain.RyaStatement;
+import mvm.rya.api.domain.RyaURI;
+import mvm.rya.api.layout.TableLayoutStrategy;
+import mvm.rya.api.persist.RyaDAO;
+import mvm.rya.api.persist.RyaDAOException;
+import mvm.rya.api.persist.RyaNamespaceManager;
+import mvm.rya.api.resolver.RyaTripleContext;
+
 public class AccumuloRyaDAO implements RyaDAO<AccumuloRdfConfiguration>, 
RyaNamespaceManager<AccumuloRdfConfiguration> {
     private static final Log logger = LogFactory.getLog(AccumuloRyaDAO.class);
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/instance/AccumuloRyaInstanceDetailsRepository.java
----------------------------------------------------------------------
diff --git 
a/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/instance/AccumuloRyaInstanceDetailsRepository.java
 
b/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/instance/AccumuloRyaInstanceDetailsRepository.java
index ec9f266..6e818b3 100644
--- 
a/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/instance/AccumuloRyaInstanceDetailsRepository.java
+++ 
b/dao/accumulo.rya/src/main/java/mvm/rya/accumulo/instance/AccumuloRyaInstanceDetailsRepository.java
@@ -63,7 +63,7 @@ import mvm.rya.api.instance.RyaDetailsRepository;
 @ParametersAreNonnullByDefault
 public class AccumuloRyaInstanceDetailsRepository implements 
RyaDetailsRepository {
 
-    private static final String INSTANCE_DETAILS_TABLE_NAME = 
"instance_details";
+    public static final String INSTANCE_DETAILS_TABLE_NAME = 
"instance_details";
 
     private static final Text ROW_ID = new Text("instance metadata");
     private static final Text COL_FAMILY = new Text("instance");
@@ -143,7 +143,7 @@ public class AccumuloRyaInstanceDetailsRepository 
implements RyaDetailsRepositor
                 try {
                     writer.close();
                 } catch (final MutationsRejectedException e) {
-                    throw new RyaDetailsRepositoryException("", e);
+                    throw new RyaDetailsRepositoryException("Could not 
initialize the Rya instance details for the instance named '" + instanceName + 
"'.", e);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/dao/accumulo.rya/src/test/java/mvm/rya/accumulo/AccumuloITBase.java
----------------------------------------------------------------------
diff --git 
a/dao/accumulo.rya/src/test/java/mvm/rya/accumulo/AccumuloITBase.java 
b/dao/accumulo.rya/src/test/java/mvm/rya/accumulo/AccumuloITBase.java
new file mode 100644
index 0000000..2a1c384
--- /dev/null
+++ b/dao/accumulo.rya/src/test/java/mvm/rya/accumulo/AccumuloITBase.java
@@ -0,0 +1,107 @@
+/**
+ * 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 mvm.rya.accumulo;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.minicluster.MiniAccumuloCluster;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.ClientCnxn;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+/**
+ * Boilerplate code for a unit test that uses a {@link MiniAccumuloCluster}.
+ * <p>
+ * It uses the same instance of {@link MiniAccumuloCluster} and just clears out
+ * any tables that were added between tests.
+ */
+public class AccumuloITBase {
+
+    // Managed the MiniAccumuloCluster
+    private MiniAccumuloClusterInstance cluster = null;
+
+    @BeforeClass
+    public static void killLoudLogs() {
+        Logger.getLogger(ClientCnxn.class).setLevel(Level.ERROR);
+    }
+
+    @Before
+    public void initCluster() throws IOException, InterruptedException, 
AccumuloException, AccumuloSecurityException {
+        cluster = new MiniAccumuloClusterInstance();
+        cluster.startMiniAccumulo();
+    }
+
+
+    @After
+    public void tearDownCluster() throws IOException, InterruptedException {
+        cluster.stopMiniAccumulo();
+    }
+
+    /**
+     * @return The {@link MiniAccumuloClusterInstance} used by the tests.
+     */
+    public MiniAccumuloClusterInstance getClusterInstance() {
+        return cluster;
+    }
+
+    /**
+     * @return The root username.
+     */
+    public String getUsername() {
+        return cluster.getUsername();
+    }
+
+    /**
+     * @return The root password.
+     */
+    public String getPassword() {
+        return cluster.getPassword();
+    }
+
+    /**
+     * @return The MiniAccumulo's zookeeper instance name.
+     */
+    public String getInstanceName() {
+        return cluster.getInstanceName();
+    }
+
+    /**
+     * @return The MiniAccumulo's zookeepers.
+     */
+    public String getZookeepers() {
+        return cluster.getZookeepers();
+    }
+
+    /**
+     * TODO doc
+     *
+     * @return
+     * @throws AccumuloSecurityException
+     * @throws AccumuloException
+     */
+    public Connector getConnector() throws AccumuloException, 
AccumuloSecurityException {
+        return cluster.getConnector();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/fcc98bd9/dao/accumulo.rya/src/test/java/mvm/rya/accumulo/AccumuloRyaITBase.java
----------------------------------------------------------------------
diff --git 
a/dao/accumulo.rya/src/test/java/mvm/rya/accumulo/AccumuloRyaITBase.java 
b/dao/accumulo.rya/src/test/java/mvm/rya/accumulo/AccumuloRyaITBase.java
new file mode 100644
index 0000000..dea227b
--- /dev/null
+++ b/dao/accumulo.rya/src/test/java/mvm/rya/accumulo/AccumuloRyaITBase.java
@@ -0,0 +1,109 @@
+/**
+ * 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 mvm.rya.accumulo;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import com.google.common.base.Optional;
+
+import mvm.rya.accumulo.instance.AccumuloRyaInstanceDetailsRepository;
+import mvm.rya.api.instance.RyaDetails;
+import mvm.rya.api.instance.RyaDetails.EntityCentricIndexDetails;
+import mvm.rya.api.instance.RyaDetails.FreeTextIndexDetails;
+import mvm.rya.api.instance.RyaDetails.GeoIndexDetails;
+import mvm.rya.api.instance.RyaDetails.JoinSelectivityDetails;
+import mvm.rya.api.instance.RyaDetails.PCJIndexDetails;
+import mvm.rya.api.instance.RyaDetails.ProspectorDetails;
+import mvm.rya.api.instance.RyaDetails.TemporalIndexDetails;
+import mvm.rya.api.instance.RyaDetailsRepository;
+import mvm.rya.api.instance.RyaDetailsRepository.AlreadyInitializedException;
+import mvm.rya.api.instance.RyaDetailsRepository.RyaDetailsRepositoryException;
+
+/**
+ * Contains boilerplate code for spinning up a Mini Accumulo Cluster and 
initializing
+ * some of the Rya stuff. We can not actually initialize an instance of Rya 
here
+ * because Sail is not available to us.
+ */
+public class AccumuloRyaITBase {
+
+    // Managed the MiniAccumuloCluster
+    private static final MiniAccumuloClusterInstance cluster = new 
MiniAccumuloClusterInstance();
+
+    // Manage the Rya instances that are hosted on the cluster
+    protected static final AtomicInteger ryaInstanceNameCounter = new 
AtomicInteger(1);
+    private String ryaInstanceName;
+
+    @BeforeClass
+    public static void initCluster() throws IOException, InterruptedException, 
AccumuloException, AccumuloSecurityException {
+        cluster.startMiniAccumulo();
+    }
+
+    @Before
+    public void prepareForNextTest() throws AccumuloException, 
AccumuloSecurityException, TableNotFoundException, AlreadyInitializedException, 
RyaDetailsRepositoryException {
+        // Get the next Rya instance name.
+        ryaInstanceName = "testInstance" + 
ryaInstanceNameCounter.getAndIncrement() + "_";
+
+        // Create Rya Details for the instance name.
+        final RyaDetailsRepository detailsRepo = new 
AccumuloRyaInstanceDetailsRepository(cluster.getConnector(), ryaInstanceName);
+
+        final RyaDetails details = RyaDetails.builder()
+                .setRyaInstanceName(ryaInstanceName)
+                .setRyaVersion("0.0.0.0")
+                .setFreeTextDetails( new FreeTextIndexDetails(true) )
+                .setEntityCentricIndexDetails( new 
EntityCentricIndexDetails(true) )
+                .setGeoIndexDetails( new GeoIndexDetails(true) )
+                .setTemporalIndexDetails( new TemporalIndexDetails(true) )
+                .setPCJIndexDetails(
+                        PCJIndexDetails.builder()
+                            .setEnabled(true) )
+                .setJoinSelectivityDetails( new JoinSelectivityDetails( 
Optional.<Date>absent() ) )
+                .setProspectorDetails( new ProspectorDetails( 
Optional.<Date>absent() ))
+                .build();
+
+        detailsRepo.initialize(details);
+    }
+
+    @AfterClass
+    public static void tearDownCluster() throws IOException, 
InterruptedException {
+        cluster.stopMiniAccumulo();
+    }
+
+    /**
+     * @return The {@link MiniAccumuloClusterInstance} used by the tests.
+     */
+    public MiniAccumuloClusterInstance getClusterInstance() {
+        return cluster;
+    }
+
+    /**
+     * @return The name of the Rya instance that is being used for the current 
test.
+     */
+    public String getRyaInstanceName() {
+        return ryaInstanceName;
+    }
+}
\ No newline at end of file

Reply via email to