You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rya.apache.org by ca...@apache.org on 2018/01/06 00:39:13 UTC
[11/15] incubator-rya git commit: RYA-104 Implemented the Rya Shell
integration with the Mongo DB interactors.
RYA-104 Implemented the Rya Shell integration with the Mongo DB interactors.
Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/9e8f4a65
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/9e8f4a65
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/9e8f4a65
Branch: refs/heads/master
Commit: 9e8f4a654f47edc7d06fa5ba7bc7011f4716549c
Parents: b642261
Author: kchilton2 <ke...@gmail.com>
Authored: Sun Dec 17 15:23:41 2017 -0500
Committer: kchilton2 <ke...@gmail.com>
Committed: Fri Jan 5 16:48:40 2018 -0500
----------------------------------------------------------------------
.../client/mongo/MongoConnectionDetails.java | 4 +-
.../org/apache/rya/shell/RyaAdminCommands.java | 112 ++++++++++++---
.../apache/rya/shell/RyaConnectionCommands.java | 84 +++++++++--
.../org/apache/rya/shell/RyaPromptProvider.java | 7 +-
.../org/apache/rya/shell/SharedShellState.java | 138 ++++++++++++++++---
.../apache/rya/shell/RyaAdminCommandsTest.java | 50 +++++--
.../apache/rya/shell/SharedShellStateTest.java | 9 +-
7 files changed, 337 insertions(+), 67 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e8f4a65/extras/indexing/src/main/java/org/apache/rya/api/client/mongo/MongoConnectionDetails.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/api/client/mongo/MongoConnectionDetails.java b/extras/indexing/src/main/java/org/apache/rya/api/client/mongo/MongoConnectionDetails.java
index 81106f9..d792289 100644
--- a/extras/indexing/src/main/java/org/apache/rya/api/client/mongo/MongoConnectionDetails.java
+++ b/extras/indexing/src/main/java/org/apache/rya/api/client/mongo/MongoConnectionDetails.java
@@ -46,7 +46,7 @@ public class MongoConnectionDetails {
* @param username - The username that was used to establish the connection. (not null)
* @param password - The password that was used to establish the connection. (not null)
* @param hostname - The hostname of the Mongo DB that was connected to. (not null)
- * @param port - The port of the Mongo DB that was connected to. (not null)
+ * @param port - The port of the Mongo DB that was connected to.
*/
public MongoConnectionDetails(
final String username,
@@ -97,7 +97,7 @@ public class MongoConnectionDetails {
return build(ryaInstanceName, null);
}
- public MongoDBRdfConfiguration build(final String ryaInstanceName, MongoClient mongoClient) {
+ public MongoDBRdfConfiguration build(final String ryaInstanceName, final MongoClient mongoClient) {
// Note, we don't use the MongoDBRdfConfigurationBuilder here because it explicitly sets
// authorizations and visibilities to an empty string if they are not set on the builder.
// If they are null in the MongoRdfConfiguration object, it may do the right thing.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e8f4a65/extras/shell/src/main/java/org/apache/rya/shell/RyaAdminCommands.java
----------------------------------------------------------------------
diff --git a/extras/shell/src/main/java/org/apache/rya/shell/RyaAdminCommands.java b/extras/shell/src/main/java/org/apache/rya/shell/RyaAdminCommands.java
index 8b86d43..cfe13dd 100644
--- a/extras/shell/src/main/java/org/apache/rya/shell/RyaAdminCommands.java
+++ b/extras/shell/src/main/java/org/apache/rya/shell/RyaAdminCommands.java
@@ -36,6 +36,7 @@ import org.apache.rya.api.client.RyaClientException;
import org.apache.rya.api.instance.RyaDetails;
import org.apache.rya.shell.SharedShellState.ConnectionState;
import org.apache.rya.shell.SharedShellState.ShellState;
+import org.apache.rya.shell.SharedShellState.StorageType;
import org.apache.rya.shell.util.InstallPrompt;
import org.apache.rya.shell.util.InstanceNamesFormatter;
import org.apache.rya.shell.util.RyaDetailsFormatter;
@@ -63,7 +64,8 @@ public class RyaAdminCommands implements CommandMarker {
public static final String LIST_INCREMENTAL_QUERIES = "list-incremental-queries";
public static final String PRINT_INSTANCE_DETAILS_CMD = "print-instance-details";
public static final String INSTALL_CMD = "install";
- public static final String INSTALL_PARAMETERS_CMD = "install-with-parameters";
+ public static final String INSTALL_ACCUMULO_PARAMETERS_CMD = "install-with-accumulo-parameters";
+ public static final String INSTALL_MONGO_PARAMETERS_CMD = "install-with-mongo-parameters";
public static final String LIST_INSTANCES_CMD = "list-instances";
public static final String UNINSTALL_CMD = "uninstall";
public static final String ADD_USER_CMD = "add-user";
@@ -99,8 +101,7 @@ public class RyaAdminCommands implements CommandMarker {
*/
@CliAvailabilityIndicator({
LIST_INSTANCES_CMD,
- INSTALL_CMD,
- INSTALL_PARAMETERS_CMD})
+ INSTALL_CMD})
public boolean areStorageCommandsAvailable() {
switch(state.getShellState().getConnectionState()) {
case CONNECTED_TO_STORAGE:
@@ -112,20 +113,52 @@ public class RyaAdminCommands implements CommandMarker {
}
/**
+ * Enables commands that only become available once the Shell has been connected to an Accumulo Rya Storage.
+ */
+ @CliAvailabilityIndicator({
+ INSTALL_ACCUMULO_PARAMETERS_CMD})
+ public boolean areAccumuloStorageCommandsAvailable() {
+ return isConnectedToStorageType(StorageType.ACCUMULO);
+ }
+
+ /**
+ * Enables commands that only become available once the Shell has been connected to an MongoDB Rya Storage.
+ */
+ @CliAvailabilityIndicator({
+ INSTALL_MONGO_PARAMETERS_CMD})
+ public boolean areMongoStorageCommandsAvailable() {
+ return isConnectedToStorageType(StorageType.MONGO);
+ }
+
+ private boolean isConnectedToStorageType(final StorageType type) {
+ // Enabled if we are connected to the specified storage type.
+ final Optional<StorageType> storageType = state.getShellState().getStorageType();
+ if(storageType.isPresent()) {
+ return areStorageCommandsAvailable() && storageType.get() == type;
+ }
+
+ // Otherwise disabled.
+ return false;
+ }
+
+ /**
* Enables commands that are always available once the Shell is connected to a Rya Instance.
*/
@CliAvailabilityIndicator({
PRINT_INSTANCE_DETAILS_CMD,
- UNINSTALL_CMD,
+ UNINSTALL_CMD})
+ public boolean areInstanceCommandsAvailable() {
+ return state.getShellState().getConnectionState() == ConnectionState.CONNECTED_TO_INSTANCE;
+ }
+
+ /**
+ * Enables commands that are available when connected to a Rya Instance that supports user management.
+ */
+ @CliAvailabilityIndicator({
ADD_USER_CMD,
REMOVE_USER_CMD})
- public boolean areInstanceCommandsAvailable() {
- switch(state.getShellState().getConnectionState()) {
- case CONNECTED_TO_INSTANCE:
- return true;
- default:
- return false;
- }
+ public boolean areUserCommandAvailable() {
+ return areInstanceCommandsAvailable() && state.getShellState().getStorageType().get() == StorageType.ACCUMULO;
}
/**
@@ -141,7 +174,8 @@ public class RyaAdminCommands implements CommandMarker {
// The PCJ commands are only available if the Shell is connected to an instance of Rya
// that is new enough to use the RyaDetailsRepository and is configured to maintain PCJs.
final ShellState shellState = state.getShellState();
- if(shellState.getConnectionState() == ConnectionState.CONNECTED_TO_INSTANCE) {
+ if(shellState.getConnectionState() == ConnectionState.CONNECTED_TO_INSTANCE &&
+ shellState.getStorageType().get() == StorageType.ACCUMULO) {
final GetInstanceDetails getInstanceDetails = shellState.getConnectedCommands().get().getGetInstanceDetails();
final String ryaInstanceName = state.getShellState().getRyaInstanceName().get();
try {
@@ -211,8 +245,8 @@ public class RyaAdminCommands implements CommandMarker {
}
}
- @CliCommand(value = INSTALL_PARAMETERS_CMD, help = "Create a new instance of Rya with command line parameters.")
- public String installWithParameters(
+ @CliCommand(value = INSTALL_ACCUMULO_PARAMETERS_CMD, help = "Create a new Accumulo instance of Rya with command line parameters.")
+ public String installWithAccumuloParameters(
@CliOption(key = {"instanceName"}, mandatory = true, help = "The name of the Rya instance to create.")
final String instanceName,
@@ -225,8 +259,9 @@ public class RyaAdminCommands implements CommandMarker {
@CliOption(key = {"enableFreeTextIndex"}, mandatory = false, help = "Use Free Text Indexing.", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true")
final boolean enableFreeTextIndex,
- @CliOption(key = {"enableGeospatialIndex"}, mandatory = false, help = "Use Geospatial Indexing.", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true")
- final boolean enableGeospatialIndex,
+ // TODO RYA-215
+// @CliOption(key = {"enableGeospatialIndex"}, mandatory = false, help = "Use Geospatial Indexing.", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true")
+// final boolean enableGeospatialIndex,
@CliOption(key = {"enableTemporalIndex"}, mandatory = false, help = "Use Temporal Indexing.", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true")
final boolean enableTemporalIndex,
@@ -246,7 +281,8 @@ public class RyaAdminCommands implements CommandMarker {
.setEnableTableHashPrefix(enableTableHashPrefix)
.setEnableEntityCentricIndex(enableEntityCentricIndex)
.setEnableFreeTextIndex(enableFreeTextIndex)
- .setEnableGeoIndex(enableGeospatialIndex)
+ // TODO RYA-215
+// .setEnableGeoIndex(enableGeospatialIndex)
.setEnableTemporalIndex(enableTemporalIndex)
.setEnablePcjIndex(enablePcjIndex)
.setFluoPcjAppName(fluoPcjAppName)
@@ -268,6 +304,48 @@ public class RyaAdminCommands implements CommandMarker {
}
}
+ @CliCommand(value = INSTALL_MONGO_PARAMETERS_CMD, help = "Create a new MongoDB instance of Rya with command line parameters.")
+ public String installWithMongoParameters(
+ @CliOption(key = {"instanceName"}, mandatory = true, help = "The name of the Rya instance to create.")
+ final String instanceName,
+
+ @CliOption(key = {"enableFreeTextIndex"}, mandatory = false, help = "Use Free Text Indexing.", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true")
+ final boolean enableFreeTextIndex,
+
+ // TODO RYA-215
+// @CliOption(key = {"enableGeospatialIndex"}, mandatory = false, help = "Use Geospatial Indexing.", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true")
+// final boolean enableGeospatialIndex,
+
+ @CliOption(key = {"enableTemporalIndex"}, mandatory = false, help = "Use Temporal Indexing.", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true")
+ final boolean enableTemporalIndex) {
+
+ // Fetch the commands that are connected to the store.
+ final RyaClient commands = state.getShellState().getConnectedCommands().get();
+
+ try {
+ final InstallConfiguration installConfig = InstallConfiguration.builder()
+ .setEnableFreeTextIndex(enableFreeTextIndex)
+ // TODO RYA-215
+// .setEnableGeoIndex(enableGeospatialIndex)
+ .setEnableTemporalIndex(enableTemporalIndex)
+ .build();
+
+ // Verify the configuration is what the user actually wants to do.
+ if (!installPrompt.promptVerified(instanceName, installConfig)) {
+ return "Skipping Installation.";
+ }
+
+ // Execute the command.
+ commands.getInstall().install(instanceName, installConfig);
+ return String.format("The Rya instance named '%s' has been installed.", instanceName);
+
+ } catch(final DuplicateInstanceNameException e) {
+ throw new RuntimeException(String.format("A Rya instance named '%s' already exists. Try again with a different name.", instanceName), e);
+ } catch (final IOException | RyaClientException e) {
+ throw new RuntimeException("Could not install a new instance of Rya. Reason: " + e.getMessage(), e);
+ }
+ }
+
@CliCommand(value = PRINT_INSTANCE_DETAILS_CMD, help = "Print information about how the Rya instance is configured.")
public String printInstanceDetails() {
// Fetch the command that is connected to the store.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e8f4a65/extras/shell/src/main/java/org/apache/rya/shell/RyaConnectionCommands.java
----------------------------------------------------------------------
diff --git a/extras/shell/src/main/java/org/apache/rya/shell/RyaConnectionCommands.java b/extras/shell/src/main/java/org/apache/rya/shell/RyaConnectionCommands.java
index f5ba451..e518968 100644
--- a/extras/shell/src/main/java/org/apache/rya/shell/RyaConnectionCommands.java
+++ b/extras/shell/src/main/java/org/apache/rya/shell/RyaConnectionCommands.java
@@ -31,7 +31,12 @@ import org.apache.rya.api.client.RyaClient;
import org.apache.rya.api.client.RyaClientException;
import org.apache.rya.api.client.accumulo.AccumuloConnectionDetails;
import org.apache.rya.api.client.accumulo.AccumuloRyaClientFactory;
+import org.apache.rya.api.client.mongo.MongoConnectionDetails;
+import org.apache.rya.api.client.mongo.MongoRyaClientFactory;
+import org.apache.rya.mongodb.MongoConnectorFactory;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
import org.apache.rya.shell.SharedShellState.ConnectionState;
+import org.apache.rya.shell.SharedShellState.StorageType;
import org.apache.rya.shell.util.ConnectorFactory;
import org.apache.rya.shell.util.PasswordPrompt;
import org.springframework.beans.factory.annotation.Autowired;
@@ -42,6 +47,7 @@ import org.springframework.shell.core.annotation.CliOption;
import org.springframework.stereotype.Component;
import com.google.common.base.Optional;
+import com.mongodb.MongoClient;
/**
* Spring Shell commands that manage the connection that is used by the shell.
@@ -52,6 +58,7 @@ public class RyaConnectionCommands implements CommandMarker {
// Command line commands.
public static final String PRINT_CONNECTION_DETAILS_CMD = "print-connection-details";
public static final String CONNECT_ACCUMULO_CMD = "connect-accumulo";
+ public static final String CONNECT_MONGO_CMD = "connect-mongo";
public static final String CONNECT_INSTANCE_CMD = "connect-rya";
public static final String DISCONNECT_COMMAND_NAME_CMD = "disconnect";
@@ -75,7 +82,7 @@ public class RyaConnectionCommands implements CommandMarker {
return true;
}
- @CliAvailabilityIndicator({CONNECT_ACCUMULO_CMD})
+ @CliAvailabilityIndicator({CONNECT_ACCUMULO_CMD, CONNECT_MONGO_CMD})
public boolean areConnectCommandsAvailable() {
return sharedState.getShellState().getConnectionState() == ConnectionState.DISCONNECTED;
}
@@ -98,17 +105,31 @@ public class RyaConnectionCommands implements CommandMarker {
@CliCommand(value = PRINT_CONNECTION_DETAILS_CMD, help = "Print information about the Shell's Rya storage connection.")
public String printConnectionDetails() {
- final Optional<AccumuloConnectionDetails> detailsHolder = sharedState.getShellState().getConnectionDetails();
-
- if(detailsHolder.isPresent()) {
- final AccumuloConnectionDetails details = detailsHolder.get();
- return "The shell is connected to an instance of Accumulo using the following parameters:\n" +
- " Username: " + details.getUsername() + "\n" +
- " Instance Name: " + details.getInstanceName() + "\n" +
- " Zookeepers: " + details.getZookeepers();
- } else {
+ // Check to see if the shell is connected to any storages.
+ final Optional<StorageType> storageType = sharedState.getShellState().getStorageType();
+ if(!storageType.isPresent()) {
return "The shell is not connected to anything.";
}
+
+ // Create a print out based on what it is connected to.
+ switch(storageType.get()) {
+ case ACCUMULO:
+ final AccumuloConnectionDetails accDetails = sharedState.getShellState().getAccumuloDetails().get();
+ return "The shell is connected to an instance of Accumulo using the following parameters:\n" +
+ " Username: " + accDetails.getUsername() + "\n" +
+ " Instance Name: " + accDetails.getInstanceName() + "\n" +
+ " Zookeepers: " + accDetails.getZookeepers();
+
+ case MONGO:
+ final MongoConnectionDetails mongoDetails = sharedState.getShellState().getMongoDetails().get();
+ return "The shell is connected to an instance of MongoDB using the following parameters:\n" +
+ " Hostname: " + mongoDetails.getHostname() + "\n" +
+ " Port: " + mongoDetails.getPort() + "\n" +
+ " Username:" + mongoDetails.getUsername();
+
+ default:
+ throw new RuntimeException("Unrecognized StorageType: " + storageType.get());
+ }
}
@CliCommand(value = CONNECT_ACCUMULO_CMD, help = "Connect the shell to an instance of Accumulo.")
@@ -138,6 +159,49 @@ public class RyaConnectionCommands implements CommandMarker {
return "Connected. You must select a Rya instance to interact with next.";
}
+ @CliCommand(value = CONNECT_MONGO_CMD, help = "Connect the shell to an instance of MongoDB.")
+ public String connectToMongo(
+ @CliOption(key = {"username"}, mandatory = true, help = "The username that will be used to connect to MongoDB.")
+ final String username,
+ @CliOption(key= {"hostname"}, mandatory = true, help = "The hostname of the MongoDB that will be connected to.")
+ final String hostname,
+ @CliOption(key= {"port"}, mandatory = true, help = "The port of the MongoDB that will be connected to.")
+ final String port) {
+
+ // Prompt the user for their password.
+ try {
+ final char[] password = passwordPrompt.getPassword();
+
+ // Set up a configuration file that connects to the specified Mongo DB.
+ final MongoDBRdfConfiguration conf = new MongoDBRdfConfiguration();
+ conf.setMongoInstance(hostname);
+ conf.setMongoPort(port);
+ conf.setMongoUser(username);
+ conf.setMongoPassword(new String(password));
+
+ // Create the singleton instance of Mongo that will be used through out the application.
+ final MongoClient client = MongoConnectorFactory.getMongoClient(conf);
+
+ // Make sure the client is closed at shutdown.
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ MongoConnectorFactory.closeMongoClient();
+ }
+ });
+
+ // Initialize the connected to Mongo shared state.
+ final MongoConnectionDetails connectionDetails = new MongoConnectionDetails(username, password, hostname, Integer.parseInt(port));
+ final RyaClient ryaClient = MongoRyaClientFactory.build(connectionDetails, client);
+ sharedState.connectedToMongo(connectionDetails, ryaClient);
+
+ } catch (final IOException e) {
+ throw new RuntimeException("Could not connection to MongoDB. Reason: " + e.getMessage(), e);
+ }
+
+ return "Connected. You must select a Rya instance to interact with next.";
+ }
+
@CliCommand(value = CONNECT_INSTANCE_CMD, help = "Connect to a specific Rya instance")
public void connectToInstance(
@CliOption(key = {"instance"}, mandatory = true, help = "The name of the Rya instance the shell will interact with.")
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e8f4a65/extras/shell/src/main/java/org/apache/rya/shell/RyaPromptProvider.java
----------------------------------------------------------------------
diff --git a/extras/shell/src/main/java/org/apache/rya/shell/RyaPromptProvider.java b/extras/shell/src/main/java/org/apache/rya/shell/RyaPromptProvider.java
index ed5f261..a7fd802 100644
--- a/extras/shell/src/main/java/org/apache/rya/shell/RyaPromptProvider.java
+++ b/extras/shell/src/main/java/org/apache/rya/shell/RyaPromptProvider.java
@@ -20,14 +20,13 @@ package org.apache.rya.shell;
import static java.util.Objects.requireNonNull;
+import org.apache.rya.shell.SharedShellState.ShellState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.shell.plugin.support.DefaultPromptProvider;
import org.springframework.stereotype.Component;
-import org.apache.rya.shell.SharedShellState.ShellState;
-
/**
* Customizes the Rya Shell's prompt.
*/
@@ -50,10 +49,10 @@ public class RyaPromptProvider extends DefaultPromptProvider {
case DISCONNECTED:
return "rya> ";
case CONNECTED_TO_STORAGE:
- return String.format("rya/%s> ", state.getConnectionDetails().get().getInstanceName());
+ return String.format("rya/%s> ", state.getAccumuloDetails().get().getInstanceName());
case CONNECTED_TO_INSTANCE:
return String.format("rya/%s:%s> ",
- state.getConnectionDetails().get().getInstanceName(),
+ state.getAccumuloDetails().get().getInstanceName(),
state.getRyaInstanceName().get());
default:
return "rya> ";
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e8f4a65/extras/shell/src/main/java/org/apache/rya/shell/SharedShellState.java
----------------------------------------------------------------------
diff --git a/extras/shell/src/main/java/org/apache/rya/shell/SharedShellState.java b/extras/shell/src/main/java/org/apache/rya/shell/SharedShellState.java
index 526b031..6c8a57c 100644
--- a/extras/shell/src/main/java/org/apache/rya/shell/SharedShellState.java
+++ b/extras/shell/src/main/java/org/apache/rya/shell/SharedShellState.java
@@ -23,17 +23,18 @@ import static java.util.Objects.requireNonNull;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
-import edu.umd.cs.findbugs.annotations.Nullable;
+import org.apache.rya.api.client.RyaClient;
+import org.apache.rya.api.client.accumulo.AccumuloConnectionDetails;
+import org.apache.rya.api.client.mongo.MongoConnectionDetails;
+
+import com.google.common.base.Optional;
+
import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
import edu.umd.cs.findbugs.annotations.NonNull;
+import edu.umd.cs.findbugs.annotations.Nullable;
import net.jcip.annotations.Immutable;
import net.jcip.annotations.ThreadSafe;
-import com.google.common.base.Optional;
-
-import org.apache.rya.api.client.RyaClient;
-import org.apache.rya.api.client.accumulo.AccumuloConnectionDetails;
-
/**
* Holds values that are shared between the various Rya command classes.
*/
@@ -86,7 +87,7 @@ public class SharedShellState {
// Store the connection details.
shellState = ShellState.builder()
.setConnectionState( ConnectionState.CONNECTED_TO_STORAGE )
- .setAccumuloConnectionDetails( connectionDetails )
+ .setAccumuloDetails( connectionDetails )
.setConnectedCommands( connectedCommands )
.build();
} finally {
@@ -95,6 +96,40 @@ public class SharedShellState {
}
/**
+ * This method indicates a shift into the {@link ConnectionState#CONNECTED_TO_STORAGE} state.
+ * <p/>
+ * Store the values used by a Mongo Rya Storage connection. This may only be called when
+ * the shell is disconnected.
+ *
+ * @param connectionDetails - Metadata about the Mongo connection. (not null)
+ * @param connectedCommands - Rya Commands that will execute against the Mongo database. (not null)
+ * @throws IllegalStateException Thrown if the shell is already connected to a Rya storage.
+ */
+ public void connectedToMongo(
+ final MongoConnectionDetails connectionDetails,
+ final RyaClient connectedCommands) throws IllegalStateException {
+ requireNonNull(connectionDetails);
+ requireNonNull(connectedCommands);
+
+ lock.lock();
+ try {
+ // Ensure the Rya Shell is disconnected.
+ if(shellState.getConnectionState() != ConnectionState.DISCONNECTED) {
+ throw new IllegalStateException("You must clear the old connection state before you may set a new connection state.");
+ }
+
+ // Store the connection details.
+ shellState = ShellState.builder()
+ .setConnectionState( ConnectionState.CONNECTED_TO_STORAGE )
+ .setMongoDetails( connectionDetails )
+ .setConnectedCommands( connectedCommands )
+ .build();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
* This method indicates a shift into the {@link ConnectionState#CONNECTED_TO_INSTANCE} state.
* <p/>
* Store the name of the Rya instance all commands will be executed against.
@@ -160,6 +195,21 @@ public class SharedShellState {
}
/**
+ * Enumerates the various types of Rya Storages the shell may connect to.
+ */
+ public static enum StorageType {
+ /**
+ * The Rya instances are stored in Accumulo.
+ */
+ ACCUMULO,
+
+ /**
+ * The Rya instances are stored in MongoDB.
+ */
+ MONGO;
+ }
+
+ /**
* Values that define the state of a Rya Shell.
*/
@Immutable
@@ -169,7 +219,9 @@ public class SharedShellState {
private final ConnectionState connectionState;
// Connection specific values.
- private final Optional<AccumuloConnectionDetails> connectionDetails;
+ private final Optional<StorageType> storageType;
+ private final Optional<AccumuloConnectionDetails> accumuloDetails;
+ private final Optional<MongoConnectionDetails> mongoDetails;
private final Optional<RyaClient> connectedCommands;
// Instance specific values.
@@ -177,11 +229,15 @@ public class SharedShellState {
private ShellState(
final ConnectionState connectionState,
- final Optional<AccumuloConnectionDetails> connectionDetails,
+ final Optional<StorageType> storageType,
+ final Optional<AccumuloConnectionDetails> accumuloDetails,
+ final Optional<MongoConnectionDetails> mongoDetails,
final Optional<RyaClient> connectedCommands,
final Optional<String> instanceName) {
this.connectionState = requireNonNull(connectionState);
- this.connectionDetails = requireNonNull(connectionDetails);
+ this.storageType = requireNonNull(storageType);
+ this.accumuloDetails = requireNonNull(accumuloDetails);
+ this.mongoDetails = requireNonNull(mongoDetails);
this.connectedCommands = requireNonNull(connectedCommands);
this.instanceName = requireNonNull(instanceName);
}
@@ -194,11 +250,28 @@ public class SharedShellState {
}
/**
+ * @return The type of storage the shell is connected to if it is connected to a storage.
+ */
+ public Optional<StorageType> getStorageType() {
+ return storageType;
+ }
+
+ /**
* @return Metadata about the Accumulo connection. The value will not be present
- * if the Rya Shell is not connected to a storage.
+ * if the Rya Shell is not connected to a storage or is connected to another type
+ * of storage.
*/
- public Optional<AccumuloConnectionDetails> getConnectionDetails() {
- return connectionDetails;
+ public Optional<AccumuloConnectionDetails> getAccumuloDetails() {
+ return accumuloDetails;
+ }
+
+ /**
+ * @return Metadata about the Mongo connection. The value will not be present
+ * if the Rya Shell is not connected to a storage or is connected to another type
+ * of storage.
+ */
+ public Optional<MongoConnectionDetails> getMongoDetails() {
+ return mongoDetails;
}
/**
@@ -220,7 +293,7 @@ public class SharedShellState {
@Override
public int hashCode() {
- return Objects.hash(connectionState, connectionDetails, connectedCommands, instanceName);
+ return Objects.hash(connectionState, accumuloDetails, connectedCommands, instanceName);
}
@Override
@@ -231,7 +304,7 @@ public class SharedShellState {
if(obj instanceof ShellState) {
final ShellState state = (ShellState)obj;
return Objects.equals(connectionState, state.connectionState) &&
- Objects.equals(connectionDetails, state.connectionDetails) &&
+ Objects.equals(accumuloDetails, state.accumuloDetails) &&
Objects.equals(connectedCommands, state.connectedCommands) &&
Objects.equals(instanceName, state.instanceName);
}
@@ -264,7 +337,9 @@ public class SharedShellState {
private ConnectionState connectionState;
// Connection specific values.
- private AccumuloConnectionDetails connectionDetails;
+ private StorageType storageType;
+ private AccumuloConnectionDetails accumuloDetails;
+ private MongoConnectionDetails mongoDetails;
private RyaClient connectedCommands;
// Instance specific values.
@@ -283,7 +358,7 @@ public class SharedShellState {
*/
public Builder(final ShellState shellState) {
this.connectionState = shellState.getConnectionState();
- this.connectionDetails = shellState.getConnectionDetails().orNull();
+ this.accumuloDetails = shellState.getAccumuloDetails().orNull();
this.connectedCommands = shellState.getConnectedCommands().orNull();
this.instanceName = shellState.getRyaInstanceName().orNull();
}
@@ -298,11 +373,30 @@ public class SharedShellState {
}
/**
- * @param connectionDetails - Metadata about the Accumulo connection.
+ * @param accumuloDetails - Metadata about the Accumulo connection.
+ * @return This {@link Builder} so that method invocations may be chained.
+ */
+ public Builder setAccumuloDetails(@Nullable final AccumuloConnectionDetails accumuloDetails) {
+ // If we are setting the details, clear any old ones.
+ if(accumuloDetails != null) {
+ this.storageType = StorageType.ACCUMULO;
+ this.mongoDetails = null;
+ }
+ this.accumuloDetails = accumuloDetails;
+ return this;
+ }
+
+ /**
+ * @param mongoDetails - Metadata about the Mongo connection.
* @return This {@link Builder} so that method invocations may be chained.
*/
- public Builder setAccumuloConnectionDetails(@Nullable final AccumuloConnectionDetails connectionDetails) {
- this.connectionDetails = connectionDetails;
+ public Builder setMongoDetails(@Nullable final MongoConnectionDetails mongoDetails) {
+ // If we are setting the details, clear any old ones.
+ if(mongoDetails != null) {
+ this.storageType = StorageType.MONGO;
+ this.accumuloDetails = null;
+ }
+ this.mongoDetails = mongoDetails;
return this;
}
@@ -330,7 +424,9 @@ public class SharedShellState {
public ShellState build() {
return new ShellState(
connectionState,
- Optional.fromNullable(connectionDetails),
+ Optional.fromNullable(storageType),
+ Optional.fromNullable(accumuloDetails),
+ Optional.fromNullable(mongoDetails),
Optional.fromNullable(connectedCommands),
Optional.fromNullable(instanceName));
}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e8f4a65/extras/shell/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java
----------------------------------------------------------------------
diff --git a/extras/shell/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java b/extras/shell/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java
index 6e21f8d..d8d5b8f 100644
--- a/extras/shell/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java
+++ b/extras/shell/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java
@@ -48,6 +48,7 @@ import org.apache.rya.api.client.RyaClient;
import org.apache.rya.api.client.RyaClientException;
import org.apache.rya.api.client.Uninstall;
import org.apache.rya.api.client.accumulo.AccumuloConnectionDetails;
+import org.apache.rya.api.client.mongo.MongoConnectionDetails;
import org.apache.rya.api.instance.RyaDetails;
import org.apache.rya.api.instance.RyaDetails.EntityCentricIndexDetails;
import org.apache.rya.api.instance.RyaDetails.FreeTextIndexDetails;
@@ -354,7 +355,7 @@ public class RyaAdminCommandsTest {
}
@Test
- public void installWithParameters() throws DuplicateInstanceNameException, RyaClientException, IOException {
+ public void installWithAccumuloParameters() throws DuplicateInstanceNameException, RyaClientException, IOException {
// Mock the object that performs the install operation.
final Install mockInstall = mock(Install.class);
@@ -368,7 +369,6 @@ public class RyaAdminCommandsTest {
final boolean enableTableHashPrefix = false;
final boolean enableEntityCentricIndex = true;
final boolean enableFreeTextIndex = false;
- final boolean enableGeospatialIndex = true;
final boolean enableTemporalIndex = false;
final boolean enablePcjIndex = true;
final String fluoPcjAppName = instanceName + "pcj_updater";
@@ -378,7 +378,6 @@ public class RyaAdminCommandsTest {
.setEnableTableHashPrefix(enableTableHashPrefix)
.setEnableEntityCentricIndex(enableEntityCentricIndex)
.setEnableFreeTextIndex(enableFreeTextIndex)
- .setEnableGeoIndex(enableGeospatialIndex)
.setEnableTemporalIndex(enableTemporalIndex)
.setEnablePcjIndex(enablePcjIndex)
.setFluoPcjAppName(fluoPcjAppName)
@@ -390,7 +389,7 @@ public class RyaAdminCommandsTest {
when(mockInstallPrompt.promptVerified(eq(instanceName), eq(installConfig))).thenReturn(true);
final RyaAdminCommands commands = new RyaAdminCommands(state, mockInstallPrompt, mock(SparqlPrompt.class), mock(UninstallPrompt.class));
- final String message = commands.installWithParameters(instanceName, enableTableHashPrefix, enableEntityCentricIndex, enableFreeTextIndex, enableGeospatialIndex, enableTemporalIndex, enablePcjIndex, fluoPcjAppName);
+ final String message = commands.installWithAccumuloParameters(instanceName, enableTableHashPrefix, enableEntityCentricIndex, enableFreeTextIndex, enableTemporalIndex, enablePcjIndex, fluoPcjAppName);
// Verify the values that were provided to the command were passed through to the Install.
verify(mockInstall).install(eq(instanceName), eq(installConfig));
@@ -401,7 +400,7 @@ public class RyaAdminCommandsTest {
}
@Test
- public void installWithParameters_userAbort() throws DuplicateInstanceNameException, RyaClientException, IOException {
+ public void installWithAccumuloParameters_userAbort() throws DuplicateInstanceNameException, RyaClientException, IOException {
// Mock the object that performs the install operation.
final Install mockInstall = mock(Install.class);
@@ -415,7 +414,6 @@ public class RyaAdminCommandsTest {
final boolean enableTableHashPrefix = false;
final boolean enableEntityCentricIndex = true;
final boolean enableFreeTextIndex = false;
- final boolean enableGeospatialIndex = true;
final boolean enableTemporalIndex = false;
final boolean enablePcjIndex = true;
final String fluoPcjAppName = instanceName + "pcj_updater";
@@ -425,7 +423,6 @@ public class RyaAdminCommandsTest {
.setEnableTableHashPrefix(enableTableHashPrefix)
.setEnableEntityCentricIndex(enableEntityCentricIndex)
.setEnableFreeTextIndex(enableFreeTextIndex)
- .setEnableGeoIndex(enableGeospatialIndex)
.setEnableTemporalIndex(enableTemporalIndex)
.setEnablePcjIndex(enablePcjIndex)
.setFluoPcjAppName(fluoPcjAppName)
@@ -437,7 +434,7 @@ public class RyaAdminCommandsTest {
when(mockInstallPrompt.promptVerified(eq(instanceName), eq(installConfig))).thenReturn(false);
final RyaAdminCommands commands = new RyaAdminCommands(state, mockInstallPrompt, mock(SparqlPrompt.class), mock(UninstallPrompt.class));
- final String message = commands.installWithParameters(instanceName, enableTableHashPrefix, enableEntityCentricIndex, enableFreeTextIndex, enableGeospatialIndex, enableTemporalIndex, enablePcjIndex, fluoPcjAppName);
+ final String message = commands.installWithAccumuloParameters(instanceName, enableTableHashPrefix, enableEntityCentricIndex, enableFreeTextIndex, enableTemporalIndex, enablePcjIndex, fluoPcjAppName);
// Verify a message is returned that indicates the success of the operation.
final String expected = "Skipping Installation.";
@@ -445,6 +442,43 @@ public class RyaAdminCommandsTest {
}
@Test
+ public void installWithMongoParameters() throws DuplicateInstanceNameException, RyaClientException, IOException {
+ // Mock the object that performs the install operation.
+ final Install mockInstall = mock(Install.class);
+
+ final RyaClient mockCommands = mock(RyaClient.class);
+ when(mockCommands.getInstall()).thenReturn( mockInstall );
+
+ final SharedShellState state = new SharedShellState();
+ state.connectedToMongo(mock(MongoConnectionDetails.class), mockCommands);
+
+ final String instanceName = "unitTests";
+ final boolean enableFreeTextIndex = false;
+ final boolean enableTemporalIndex = false;
+
+ // Execute the command.
+ final InstallConfiguration installConfig = InstallConfiguration.builder()
+ .setEnableFreeTextIndex(enableFreeTextIndex)
+ .setEnableTemporalIndex(enableTemporalIndex)
+ .build();
+
+ final InstallPrompt mockInstallPrompt = mock(InstallPrompt.class);
+ when(mockInstallPrompt.promptInstanceName()).thenReturn( instanceName );
+ when(mockInstallPrompt.promptInstallConfiguration(instanceName)).thenReturn( installConfig );
+ when(mockInstallPrompt.promptVerified(eq(instanceName), eq(installConfig))).thenReturn(true);
+
+ final RyaAdminCommands commands = new RyaAdminCommands(state, mockInstallPrompt, mock(SparqlPrompt.class), mock(UninstallPrompt.class));
+ final String message = commands.installWithMongoParameters(instanceName, enableFreeTextIndex, enableTemporalIndex);
+
+ // Verify the values that were provided to the command were passed through to the Install.
+ verify(mockInstall).install(eq(instanceName), eq(installConfig));
+
+ // Verify a message is returned that indicates the success of the operation.
+ final String expected = "The Rya instance named 'unitTests' has been installed.";
+ assertEquals(expected, message);
+ }
+
+ @Test
public void listInstances() throws RyaClientException, IOException {
// Mock the object that performs the list operation.
final ListInstances mockListInstances = mock(ListInstances.class);
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/9e8f4a65/extras/shell/src/test/java/org/apache/rya/shell/SharedShellStateTest.java
----------------------------------------------------------------------
diff --git a/extras/shell/src/test/java/org/apache/rya/shell/SharedShellStateTest.java b/extras/shell/src/test/java/org/apache/rya/shell/SharedShellStateTest.java
index e79d186..b5f136c 100644
--- a/extras/shell/src/test/java/org/apache/rya/shell/SharedShellStateTest.java
+++ b/extras/shell/src/test/java/org/apache/rya/shell/SharedShellStateTest.java
@@ -21,12 +21,11 @@ package org.apache.rya.shell;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
-import org.junit.Test;
-
import org.apache.rya.api.client.RyaClient;
import org.apache.rya.api.client.accumulo.AccumuloConnectionDetails;
import org.apache.rya.shell.SharedShellState.ConnectionState;
import org.apache.rya.shell.SharedShellState.ShellState;
+import org.junit.Test;
/**
* Tests the methods of {@link SharedShellState}.
@@ -57,7 +56,7 @@ public class SharedShellStateTest {
// Verify the state.
final ShellState expected = ShellState.builder()
.setConnectionState(ConnectionState.CONNECTED_TO_STORAGE)
- .setAccumuloConnectionDetails(connectionDetails)
+ .setAccumuloDetails(connectionDetails)
.setConnectedCommands(connectedCommands)
.build();
@@ -92,7 +91,7 @@ public class SharedShellStateTest {
// Verify the state.
final ShellState expected = ShellState.builder()
.setConnectionState(ConnectionState.CONNECTED_TO_INSTANCE)
- .setAccumuloConnectionDetails(connectionDetails)
+ .setAccumuloDetails(connectionDetails)
.setConnectedCommands(connectedCommands)
.setRyaInstanceName("instance")
.build();
@@ -118,7 +117,7 @@ public class SharedShellStateTest {
// Verify the state.
final ShellState expected = ShellState.builder()
.setConnectionState(ConnectionState.CONNECTED_TO_INSTANCE)
- .setAccumuloConnectionDetails(connectionDetails)
+ .setAccumuloDetails(connectionDetails)
.setConnectedCommands(connectedCommands)
.setRyaInstanceName("secondInstance")
.build();