RYA-110 Add Rya Uninstall command to the Rya Console. Closes #94
Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/5c54c293 Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/5c54c293 Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/5c54c293 Branch: refs/heads/master Commit: 5c54c2935a5de4a5bec133708ace2792084ecea3 Parents: ab4fca4 Author: Kevin Chilton <[email protected]> Authored: Thu Sep 15 16:12:00 2016 -0400 Committer: Aaron Mihalik <[email protected]> Committed: Tue Nov 1 10:54:04 2016 -0400 ---------------------------------------------------------------------- .../org/apache/rya/api/client/RyaClient.java | 14 ++- .../org/apache/rya/api/client/Uninstall.java | 38 ++++++++ .../accumulo/AccumuloConnectionDetails.java | 2 +- .../accumulo/AccumuloRyaClientFactory.java | 3 +- .../api/client/accumulo/AccumuloUninstall.java | 96 ++++++++++++++++++++ .../api/client/accumulo/AccumuloInstallIT.java | 7 +- .../client/accumulo/AccumuloUninstallIT.java | 82 +++++++++++++++++ extras/rya.console/pom.xml | 9 +- .../org/apache/rya/shell/RyaAdminCommands.java | 35 ++++++- .../apache/rya/shell/util/UninstallPrompt.java | 58 ++++++++++++ .../apache/rya/shell/RyaAdminCommandsTest.java | 67 ++++++++++++-- .../src/test/resources/RyaShellTest-context.xml | 5 + 12 files changed, 395 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/common/rya.api/src/main/java/org/apache/rya/api/client/RyaClient.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/client/RyaClient.java b/common/rya.api/src/main/java/org/apache/rya/api/client/RyaClient.java index b290957..d4b5047 100644 --- a/common/rya.api/src/main/java/org/apache/rya/api/client/RyaClient.java +++ b/common/rya.api/src/main/java/org/apache/rya/api/client/RyaClient.java @@ -40,6 +40,7 @@ public class RyaClient { private final ListInstances listInstances; private final AddUser addUser; private final RemoveUser removeUser; + private final Uninstall uninstall; /** * Constructs an instance of {@link RyaClient}. @@ -53,16 +54,18 @@ public class RyaClient { final InstanceExists instanceExists, final ListInstances listInstances, final AddUser addUser, - final RemoveUser removeUser) { + final RemoveUser removeUser, + final Uninstall uninstall) { this.install = requireNonNull(install); this.createPcj = requireNonNull(createPcj); this.deletePcj = requireNonNull(deletePcj); - bactchUpdatePCJ = requireNonNull(batchUpdatePcj); + this.bactchUpdatePCJ = requireNonNull(batchUpdatePcj); this.getInstanceDetails = requireNonNull(getInstanceDetails); this.instanceExists = requireNonNull(instanceExists); this.listInstances = requireNonNull(listInstances); this.addUser = requireNonNull(addUser); this.removeUser = requireNonNull(removeUser); + this.uninstall = requireNonNull(uninstall); } /** @@ -130,4 +133,11 @@ public class RyaClient { public RemoveUser getRemoveUser() { return removeUser; } + + /** + * @return An instance of {@link Uninstall} that is connected to a Rya storage. + */ + public Uninstall getUninstall() { + return uninstall; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/common/rya.api/src/main/java/org/apache/rya/api/client/Uninstall.java ---------------------------------------------------------------------- diff --git a/common/rya.api/src/main/java/org/apache/rya/api/client/Uninstall.java b/common/rya.api/src/main/java/org/apache/rya/api/client/Uninstall.java new file mode 100644 index 0000000..b88f305 --- /dev/null +++ b/common/rya.api/src/main/java/org/apache/rya/api/client/Uninstall.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 org.apache.rya.api.client; + +import edu.umd.cs.findbugs.annotations.DefaultAnnotation; +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * Uninstalls an instannce of Rya. + */ +@DefaultAnnotation(NonNull.class) +public interface Uninstall { + + /** + * Uninstalls an instance of Rya. + * + * @param instanceName - Indicates which Rya instance to uninstalled. (not null) + * @throws InstanceDoesNotExistException The instance of Rya already doesn't exist. + * @throws RyaClientException Something caused the command to fail. + */ + public void uninstall(final String instanceName) throws InstanceDoesNotExistException, RyaClientException; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloConnectionDetails.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloConnectionDetails.java b/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloConnectionDetails.java index a746bf1..f3753a8 100644 --- a/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloConnectionDetails.java +++ b/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloConnectionDetails.java @@ -33,7 +33,7 @@ public class AccumuloConnectionDetails { private final String username; private final char[] password; private final String instanceName; - private final String zookeepers; + private final String zookeepers; /** * Constructs an instance of {@link AccumuloConnectionDetails}. http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloRyaClientFactory.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloRyaClientFactory.java b/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloRyaClientFactory.java index 02c461f..0e642d9 100644 --- a/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloRyaClientFactory.java +++ b/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloRyaClientFactory.java @@ -57,6 +57,7 @@ public class AccumuloRyaClientFactory { new AccumuloInstanceExists(connectionDetails, connector), new AccumuloListInstances(connectionDetails, connector), new AccumuloAddUser(connectionDetails, connector), - new AccumuloRemoveUser(connectionDetails, connector)); + new AccumuloRemoveUser(connectionDetails, connector), + new AccumuloUninstall(connectionDetails, connector)); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloUninstall.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloUninstall.java b/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloUninstall.java new file mode 100644 index 0000000..96de16c --- /dev/null +++ b/extras/indexing/src/main/java/org/apache/rya/api/client/accumulo/AccumuloUninstall.java @@ -0,0 +1,96 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.rya.api.client.accumulo; + +import static java.util.Objects.requireNonNull; + +import java.util.List; + +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.core.client.TableNotFoundException; +import org.apache.accumulo.core.client.admin.TableOperations; +import org.apache.log4j.Logger; +import org.apache.rya.accumulo.utils.RyaTableNames; +import org.apache.rya.api.client.InstanceDoesNotExistException; +import org.apache.rya.api.client.InstanceExists; +import org.apache.rya.api.client.RyaClientException; +import org.apache.rya.api.client.Uninstall; +import org.apache.rya.api.instance.RyaDetailsRepository.RyaDetailsRepositoryException; +import org.apache.rya.indexing.pcj.storage.PrecomputedJoinStorage.PCJStorageException; + +import edu.umd.cs.findbugs.annotations.DefaultAnnotation; +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * An Accumulo implementation of the {@link Uninstall} command. + */ +@DefaultAnnotation(NonNull.class) +public class AccumuloUninstall extends AccumuloCommand implements Uninstall { + + private static final Logger log = Logger.getLogger(AccumuloUninstall.class); + + private final InstanceExists instanceExists; + + /** + * Constructs an instance of {@link AccumuloUninstall}. + * + * @param connectionDetails - Details about the values that were used to create + * the connector to the cluster. (not null) + * @param connector - Provides programmatic access to the instance of Accumulo + * that hosts Rya instance. (not null) + */ + public AccumuloUninstall(final AccumuloConnectionDetails connectionDetails, final Connector connector) { + super(connectionDetails, connector); + instanceExists = new AccumuloInstanceExists(connectionDetails, connector); + } + + @Override + public void uninstall(final String ryaInstanceName) throws InstanceDoesNotExistException, RyaClientException { + requireNonNull(ryaInstanceName); + + // Ensure the Rya Instance exists. + if(!instanceExists.exists(ryaInstanceName)) { + throw new InstanceDoesNotExistException(String.format("There is no Rya instance named '%s'.", ryaInstanceName)); + } + + try { + // Build the list of tables that are present within the Rya instance. + final List<String> tables = new RyaTableNames().getTableNames(ryaInstanceName, getConnector()); + + // Delete them. + final TableOperations tableOps = getConnector().tableOperations(); + for(final String table : tables) { + try { + tableOps.delete(table); + } catch(final TableNotFoundException e) { + log.warn("Uninstall could not delete table named '" + table + "' because it does not exist. " + + "Something else is also deleting tables."); + } + } + } catch (PCJStorageException | RyaDetailsRepositoryException e) { + throw new RyaClientException("Could not uninstall the Rya instance named '" + ryaInstanceName + + "' because we could not determine which tables are associated with it.", e); + } catch (AccumuloException | AccumuloSecurityException e) { + throw new RyaClientException("Could not uninstall the Rya instance named '" + ryaInstanceName + + "' because of a problem interacting with Accumulo..", e); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/indexing/src/test/java/org/apache/rya/api/client/accumulo/AccumuloInstallIT.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/org/apache/rya/api/client/accumulo/AccumuloInstallIT.java b/extras/indexing/src/test/java/org/apache/rya/api/client/accumulo/AccumuloInstallIT.java index a8e4e5c..739d216 100644 --- a/extras/indexing/src/test/java/org/apache/rya/api/client/accumulo/AccumuloInstallIT.java +++ b/extras/indexing/src/test/java/org/apache/rya/api/client/accumulo/AccumuloInstallIT.java @@ -18,10 +18,10 @@ */ package org.apache.rya.api.client.accumulo; +import static org.junit.Assert.assertTrue; + import org.apache.accumulo.core.client.AccumuloException; import org.apache.accumulo.core.client.AccumuloSecurityException; -import org.junit.Test; - import org.apache.rya.accumulo.AccumuloITBase; import org.apache.rya.api.client.Install; import org.apache.rya.api.client.Install.DuplicateInstanceNameException; @@ -30,6 +30,7 @@ import org.apache.rya.api.client.InstanceExists; import org.apache.rya.api.client.RyaClientException; import org.apache.rya.api.instance.RyaDetailsRepository.NotInitializedException; import org.apache.rya.api.instance.RyaDetailsRepository.RyaDetailsRepositoryException; +import org.junit.Test; /** * Integration tests the methods of {@link AccumuloInstall}. @@ -61,7 +62,7 @@ public class AccumuloInstallIT extends AccumuloITBase { // Check that the instance exists. final InstanceExists instanceExists = new AccumuloInstanceExists(connectionDetails, getConnector()); - instanceExists.exists(instanceName); + assertTrue( instanceExists.exists(instanceName) ); } @Test(expected = DuplicateInstanceNameException.class) http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/indexing/src/test/java/org/apache/rya/api/client/accumulo/AccumuloUninstallIT.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/org/apache/rya/api/client/accumulo/AccumuloUninstallIT.java b/extras/indexing/src/test/java/org/apache/rya/api/client/accumulo/AccumuloUninstallIT.java new file mode 100644 index 0000000..7f79efb --- /dev/null +++ b/extras/indexing/src/test/java/org/apache/rya/api/client/accumulo/AccumuloUninstallIT.java @@ -0,0 +1,82 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.rya.api.client.accumulo; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.apache.rya.accumulo.AccumuloITBase; +import org.apache.rya.api.client.Install; +import org.apache.rya.api.client.Install.InstallConfiguration; +import org.apache.rya.api.client.InstanceDoesNotExistException; +import org.apache.rya.api.client.InstanceExists; +import org.apache.rya.api.client.Uninstall; +import org.junit.Test; + +/** + * Integration tests the methods of {@link AccumuloUninstall}. + */ +public class AccumuloUninstallIT extends AccumuloITBase { + + @Test(expected = InstanceDoesNotExistException.class) + public void instanceDoesNotExist() throws Exception { + final AccumuloConnectionDetails connectionDetails = new AccumuloConnectionDetails( + getUsername(), + getPassword().toCharArray(), + getInstanceName(), + getZookeepers()); + + new AccumuloUninstall(connectionDetails, getConnector()).uninstall("instance_that_does_not_exist"); + } + + @Test + public void uninstall() throws Exception { + // Install an instance of Rya. + final InstallConfiguration installConfig = InstallConfiguration.builder() + .setEnableTableHashPrefix(true) + .setEnableEntityCentricIndex(true) + .setEnableFreeTextIndex(true) + .setEnableTemporalIndex(true) + .setEnablePcjIndex(true) + .setEnableGeoIndex(true) + .setFluoPcjAppName("fluo_app_name") + .build(); + + final AccumuloConnectionDetails connectionDetails = new AccumuloConnectionDetails( + getUsername(), + getPassword().toCharArray(), + getInstanceName(), + getZookeepers()); + + final Install install = new AccumuloInstall(connectionDetails, getConnector()); + final String ryaInstanceName = "testInstance_"; + install.install(ryaInstanceName, installConfig); + + // Check that the instance exists. + final InstanceExists instanceExists = new AccumuloInstanceExists(connectionDetails, getConnector()); + assertTrue( instanceExists.exists(ryaInstanceName) ); + + // Uninstall the instance of Rya. + final Uninstall uninstall = new AccumuloUninstall(connectionDetails, getConnector()); + uninstall.uninstall(ryaInstanceName); + + // Verify that it no longer exists. + assertFalse( instanceExists.exists(ryaInstanceName) ); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/rya.console/pom.xml ---------------------------------------------------------------------- diff --git a/extras/rya.console/pom.xml b/extras/rya.console/pom.xml index 09a470f..779cf42 100644 --- a/extras/rya.console/pom.xml +++ b/extras/rya.console/pom.xml @@ -155,13 +155,12 @@ <mainClass>org.springframework.shell.Bootstrap</mainClass> </transformer> </transformers> - - <!-- - Shading signed JARs will fail without this. - http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar - --> <filters> <filter> + <!-- + Shading signed JARs will fail without this. + http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar + --> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/rya.console/src/main/java/org/apache/rya/shell/RyaAdminCommands.java ---------------------------------------------------------------------- diff --git a/extras/rya.console/src/main/java/org/apache/rya/shell/RyaAdminCommands.java b/extras/rya.console/src/main/java/org/apache/rya/shell/RyaAdminCommands.java index 7e8b71f..5493170 100644 --- a/extras/rya.console/src/main/java/org/apache/rya/shell/RyaAdminCommands.java +++ b/extras/rya.console/src/main/java/org/apache/rya/shell/RyaAdminCommands.java @@ -37,6 +37,7 @@ import org.apache.rya.shell.util.InstallPrompt; import org.apache.rya.shell.util.InstanceNamesFormatter; import org.apache.rya.shell.util.RyaDetailsFormatter; import org.apache.rya.shell.util.SparqlPrompt; +import org.apache.rya.shell.util.UninstallPrompt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.annotation.CliAvailabilityIndicator; @@ -64,6 +65,7 @@ public class RyaAdminCommands implements CommandMarker { private final SharedShellState state; private final InstallPrompt installPrompt; private final SparqlPrompt sparqlPrompt; + private final UninstallPrompt uninstallPrompt; /** * Constructs an instance of {@link RyaAdminCommands}. @@ -71,12 +73,18 @@ public class RyaAdminCommands implements CommandMarker { * @param state - Holds shared state between all of the command classes. (not null) * @param installPrompt - Prompts a user for installation details. (not null) * @param sparqlPrompt - Prompts a user for a SPARQL query. (not null) + * @param uninstallPrompt - Prompts a user when uninstalling. (not null) */ @Autowired - public RyaAdminCommands(final SharedShellState state, final InstallPrompt installPrompt, final SparqlPrompt sparqlPrompt) { + public RyaAdminCommands( + final SharedShellState state, + final InstallPrompt installPrompt, + final SparqlPrompt sparqlPrompt, + final UninstallPrompt uninstallPrompt) { this.state = requireNonNull( state ); this.installPrompt = requireNonNull(installPrompt); this.sparqlPrompt = requireNonNull(sparqlPrompt); + this.uninstallPrompt = requireNonNull(uninstallPrompt); } /** @@ -290,4 +298,29 @@ public class RyaAdminCommands implements CommandMarker { throw new RuntimeException("The user's access could not be revoked. Provided reason: " + e.getMessage(), e); } } + + @CliCommand(value = UNINSTALL_CMD, help = "Uninstall an instance of Rya.") + public String uninstall() { + // Fetch the command that is connected to the store. + final ShellState shellState = state.getShellState(); + final RyaClient commands = shellState.getConnectedCommands().get(); + final String ryaInstanceName = shellState.getRyaInstanceName().get(); + + try { + // Make sure the user meant to uninstall the Rya instance. + if(!uninstallPrompt.promptAreYouSure(ryaInstanceName)) { + return "Cancelled."; + } + + // Perform the uninstall. + commands.getUninstall().uninstall(ryaInstanceName); + + } catch (final InstanceDoesNotExistException e) { + throw new RuntimeException(String.format("A Rya instance named '%s' does not exist.", ryaInstanceName), e); + } catch (final IOException | RyaClientException e) { + throw new RuntimeException("The Rya instance could not be uninstalled. Provided reason: " + e.getMessage(), e); + } + + return "The Rya instance named '" + ryaInstanceName +"' has been uninstalled."; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/rya.console/src/main/java/org/apache/rya/shell/util/UninstallPrompt.java ---------------------------------------------------------------------- diff --git a/extras/rya.console/src/main/java/org/apache/rya/shell/util/UninstallPrompt.java b/extras/rya.console/src/main/java/org/apache/rya/shell/util/UninstallPrompt.java new file mode 100644 index 0000000..628727c --- /dev/null +++ b/extras/rya.console/src/main/java/org/apache/rya/shell/util/UninstallPrompt.java @@ -0,0 +1,58 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.rya.shell.util; + +import static java.util.Objects.requireNonNull; + +import java.io.IOException; + +import com.google.common.base.Optional; + +import edu.umd.cs.findbugs.annotations.DefaultAnnotation; +import edu.umd.cs.findbugs.annotations.NonNull; +import jline.console.ConsoleReader; + +/** + * A mechanism for prompting a user of the application to ensure they want to + * uninstall an instance of Rya. + */ +@DefaultAnnotation(NonNull.class) +public interface UninstallPrompt { + + /** + * Prompt the user to make sure they want to uninstall the instance of Rya. + * + * @param ryaInstanceName - The name of the Rya instance being prompted for. (not null) + * @return The value they entered. + * @throws IOException There was a problem reading the values. + */ + public boolean promptAreYouSure(final String ryaInstanceName) throws IOException; + + /** + * Prompts a user for uninstall information using a JLine {@link ConsoleReader}. + */ + public static class JLineUninstallPrompt extends JLinePrompt implements UninstallPrompt { + @Override + public boolean promptAreYouSure(final String ryaInstanceName) throws IOException { + requireNonNull(ryaInstanceName); + return promptBoolean("Are you sure you want to uninstall this instance of Rya named '" + + ryaInstanceName + "'? ", Optional.<Boolean>absent()); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/rya.console/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.console/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java b/extras/rya.console/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java index 4aa1210..a5b73f2 100644 --- a/extras/rya.console/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java +++ b/extras/rya.console/src/test/java/org/apache/rya/shell/RyaAdminCommandsTest.java @@ -21,6 +21,7 @@ package org.apache.rya.shell; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -41,6 +42,7 @@ import org.apache.rya.api.client.ListInstances; import org.apache.rya.api.client.RemoveUser; 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.instance.RyaDetails; import org.apache.rya.api.instance.RyaDetails.EntityCentricIndexDetails; @@ -54,6 +56,7 @@ import org.apache.rya.api.instance.RyaDetails.ProspectorDetails; import org.apache.rya.api.instance.RyaDetails.TemporalIndexDetails; import org.apache.rya.shell.util.InstallPrompt; import org.apache.rya.shell.util.SparqlPrompt; +import org.apache.rya.shell.util.UninstallPrompt; import org.junit.Test; import com.google.common.base.Optional; @@ -84,7 +87,7 @@ public class RyaAdminCommandsTest { when(mockSparqlPrompt.getSparql()).thenReturn(sparql); // Execute the command. - final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mockSparqlPrompt); + final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mockSparqlPrompt, mock(UninstallPrompt.class)); final String message = commands.createPcj(); // Verify the values that were provided to the command were passed through to CreatePCJ. @@ -111,7 +114,7 @@ public class RyaAdminCommandsTest { // Execute the command. final String pcjId = "123412342"; - final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class)); + final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class), mock(UninstallPrompt.class)); final String message = commands.deletePcj(pcjId); // Verify the values that were provided to the command were passed through to the DeletePCJ. @@ -166,7 +169,7 @@ public class RyaAdminCommandsTest { state.connectedToInstance(instanceName); // Execute the command. - final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class)); + final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class), mock(UninstallPrompt.class)); final String message = commands.getInstanceDetails(); // Verify the values that were provided to the command were passed through to the GetInstanceDetails. @@ -228,7 +231,7 @@ public class RyaAdminCommandsTest { when(mockInstallPrompt.promptInstallConfiguration()).thenReturn( installConfig ); when(mockInstallPrompt.promptVerified(eq(instanceName), eq(installConfig))).thenReturn(true); - final RyaAdminCommands commands = new RyaAdminCommands(state, mockInstallPrompt, mock(SparqlPrompt.class)); + final RyaAdminCommands commands = new RyaAdminCommands(state, mockInstallPrompt, mock(SparqlPrompt.class), mock(UninstallPrompt.class)); final String message = commands.install(); // Verify the values that were provided to the command were passed through to the Install. @@ -254,7 +257,7 @@ public class RyaAdminCommandsTest { state.connectedToInstance("b"); // Execute the command. - final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class)); + final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class), mock(UninstallPrompt.class)); final String message = commands.listInstances(); // Verify a message is returned that lists the the instances. @@ -280,7 +283,7 @@ public class RyaAdminCommandsTest { state.connectedToInstance("test_instance"); // Execute the command. - final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class)); + final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class), mock(UninstallPrompt.class)); commands.addUser("alice"); // Verify the add request was forwarded to the client. @@ -300,10 +303,58 @@ public class RyaAdminCommandsTest { state.connectedToInstance("test_instance"); // Execute the command. - final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class)); + final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class), mock(UninstallPrompt.class)); commands.removeUser("alice"); // Verify the add request was forwarded to the client. verify(mockRemoveUser).removeUser(eq("test_instance"), eq("alice")); } -} \ No newline at end of file + + @Test + public void uninstall_yes() throws Exception { + // Mock the object that performs the Uninstall command. + final Uninstall mockUninstall = mock(Uninstall.class); + + // Mock a prompt that says the user does want to uninstall it. + final UninstallPrompt uninstallPrompt = mock(UninstallPrompt.class); + when(uninstallPrompt.promptAreYouSure( eq("test_instance") )).thenReturn(true); + + final RyaClient mockClient = mock(RyaClient.class); + when(mockClient.getUninstall()).thenReturn( mockUninstall ); + + final SharedShellState state = new SharedShellState(); + state.connectedToAccumulo(mock(AccumuloConnectionDetails.class), mockClient); + state.connectedToInstance("test_instance"); + + // Execute the command. + final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class), uninstallPrompt); + commands.uninstall(); + + // Verify the request was forwarded to the client. + verify(mockUninstall).uninstall(eq("test_instance")); + } + + @Test + public void uninstall_no() throws Exception { + // Mock the object that performs the Uninstall command. + final Uninstall mockUninstall = mock(Uninstall.class); + + // Mock a prompt that says the user does want to uninstall it. + final UninstallPrompt uninstallPrompt = mock(UninstallPrompt.class); + when(uninstallPrompt.promptAreYouSure( eq("test_instance") )).thenReturn(false); + + final RyaClient mockClient = mock(RyaClient.class); + when(mockClient.getUninstall()).thenReturn( mockUninstall ); + + final SharedShellState state = new SharedShellState(); + state.connectedToAccumulo(mock(AccumuloConnectionDetails.class), mockClient); + state.connectedToInstance("test_instance"); + + // Execute the command. + final RyaAdminCommands commands = new RyaAdminCommands(state, mock(InstallPrompt.class), mock(SparqlPrompt.class), uninstallPrompt); + commands.uninstall(); + + // Verify the request was forwarded to the client. + verify(mockUninstall, never()).uninstall(eq("test_instance")); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/5c54c293/extras/rya.console/src/test/resources/RyaShellTest-context.xml ---------------------------------------------------------------------- diff --git a/extras/rya.console/src/test/resources/RyaShellTest-context.xml b/extras/rya.console/src/test/resources/RyaShellTest-context.xml index bb91f68..f841129 100644 --- a/extras/rya.console/src/test/resources/RyaShellTest-context.xml +++ b/extras/rya.console/src/test/resources/RyaShellTest-context.xml @@ -45,6 +45,11 @@ <bean id="sparqlPrompt" class="org.mockito.Mockito" factory-method="mock"> <constructor-arg value="org.apache.rya.shell.util.SparqlPrompt"/> </bean> + + <!-- We use a mock Uninstall Prompt here to simulate a user entering the installation configuration. --> + <bean id="uninstallPrompt" class="org.mockito.Mockito" factory-method="mock"> + <constructor-arg value="org.apache.rya.shell.util.UninstallPrompt"/> + </bean> <!-- Define each of the beans that hold onto commands used by the shell. --> <bean id="ryaConnectionCommands" class="org.apache.rya.shell.RyaConnectionCommands" />
