SQOOP-1454: Sqoop2: From/To: Add client support for supported directions (Abraham Elmahrek via Jarek Jarcec Cecho)
Project: http://git-wip-us.apache.org/repos/asf/sqoop/repo Commit: http://git-wip-us.apache.org/repos/asf/sqoop/commit/27fb31d4 Tree: http://git-wip-us.apache.org/repos/asf/sqoop/tree/27fb31d4 Diff: http://git-wip-us.apache.org/repos/asf/sqoop/diff/27fb31d4 Branch: refs/heads/SQOOP-1367 Commit: 27fb31d42e7e76ca14def568e454121437f4e9e5 Parents: 3d539dd Author: Jarek Jarcec Cecho <[email protected]> Authored: Sun Sep 21 12:42:10 2014 -0700 Committer: Abraham Elmahrek <[email protected]> Committed: Thu Oct 9 17:58:18 2014 -0700 ---------------------------------------------------------------------- .../sqoop/common/SupportedDirections.java | 41 ++++++ .../java/org/apache/sqoop/model/MConnector.java | 6 + .../sqoop/common/TestSupportedDirections.java | 55 ++++++++ .../org/apache/sqoop/model/TestMConnector.java | 127 ++++++++++++------- .../sqoop/connector/ConnectorHandler.java | 4 - .../sqoop/shell/ShowConnectorFunction.java | 37 +++++- .../org/apache/sqoop/shell/core/Constants.java | 2 + .../main/resources/shell-resource.properties | 5 +- 8 files changed, 226 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sqoop/blob/27fb31d4/common/src/main/java/org/apache/sqoop/common/SupportedDirections.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/sqoop/common/SupportedDirections.java b/common/src/main/java/org/apache/sqoop/common/SupportedDirections.java new file mode 100644 index 0000000..25ba276 --- /dev/null +++ b/common/src/main/java/org/apache/sqoop/common/SupportedDirections.java @@ -0,0 +1,41 @@ +/** + * 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.sqoop.common; + +/** + * Represents which Directions are supported. + */ +public class SupportedDirections { + private boolean from; + private boolean to; + + public SupportedDirections(boolean from, boolean to) { + this.from = from; + this.to = to; + } + + /** + * Check if direction is supported. + * @param direction + * @return boolean + */ + public boolean isDirectionSupported(Direction direction) { + return direction == Direction.FROM && from + || direction == Direction.TO && to; + } +} http://git-wip-us.apache.org/repos/asf/sqoop/blob/27fb31d4/common/src/main/java/org/apache/sqoop/model/MConnector.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/sqoop/model/MConnector.java b/common/src/main/java/org/apache/sqoop/model/MConnector.java index 335a0cc..3dc1014 100644 --- a/common/src/main/java/org/apache/sqoop/model/MConnector.java +++ b/common/src/main/java/org/apache/sqoop/model/MConnector.java @@ -20,6 +20,7 @@ package org.apache.sqoop.model; import org.apache.sqoop.common.Direction; import org.apache.sqoop.common.DirectionError; import org.apache.sqoop.common.SqoopException; +import org.apache.sqoop.common.SupportedDirections; /** * Connector metadata. @@ -139,4 +140,9 @@ public final class MConnector extends MPersistableEntity implements MClonable { public void setVersion(String version) { this.version = version; } + + public SupportedDirections getSupportedDirections() { + return new SupportedDirections(this.getJobForms(Direction.FROM) != null, + this.getJobForms(Direction.TO) != null); + } } http://git-wip-us.apache.org/repos/asf/sqoop/blob/27fb31d4/common/src/test/java/org/apache/sqoop/common/TestSupportedDirections.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/sqoop/common/TestSupportedDirections.java b/common/src/test/java/org/apache/sqoop/common/TestSupportedDirections.java new file mode 100644 index 0000000..4fbaf82 --- /dev/null +++ b/common/src/test/java/org/apache/sqoop/common/TestSupportedDirections.java @@ -0,0 +1,55 @@ +/** + * 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.sqoop.common; + +import org.junit.Assert; +import org.junit.Test; + +public class TestSupportedDirections { + + @Test + public void testIsDirectionSupported() { + // Both + SupportedDirections supportedDirections = new SupportedDirections(true, true); + Assert.assertTrue( + supportedDirections.isDirectionSupported(Direction.FROM)); + Assert.assertTrue( + supportedDirections.isDirectionSupported(Direction.TO)); + + // FROM + supportedDirections = new SupportedDirections(true, false); + Assert.assertTrue( + supportedDirections.isDirectionSupported(Direction.FROM)); + Assert.assertFalse( + supportedDirections.isDirectionSupported(Direction.TO)); + + // TO + supportedDirections = new SupportedDirections(false, true); + Assert.assertFalse( + supportedDirections.isDirectionSupported(Direction.FROM)); + Assert.assertTrue( + supportedDirections.isDirectionSupported(Direction.TO)); + + // NONE + supportedDirections = new SupportedDirections(false, false); + Assert.assertFalse( + supportedDirections.isDirectionSupported(Direction.FROM)); + Assert.assertFalse( + supportedDirections.isDirectionSupported(Direction.TO)); + } +} http://git-wip-us.apache.org/repos/asf/sqoop/blob/27fb31d4/common/src/test/java/org/apache/sqoop/model/TestMConnector.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/sqoop/model/TestMConnector.java b/common/src/test/java/org/apache/sqoop/model/TestMConnector.java index 9672d9d..3fde47b 100644 --- a/common/src/test/java/org/apache/sqoop/model/TestMConnector.java +++ b/common/src/test/java/org/apache/sqoop/model/TestMConnector.java @@ -20,8 +20,10 @@ package org.apache.sqoop.model; import static org.junit.Assert.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.apache.sqoop.common.Direction; import org.junit.Test; /** @@ -29,6 +31,34 @@ import org.junit.Test; */ public class TestMConnector { + private MConnector createConnector(List<Direction> supportedDirections) { + List<MForm> forms = new ArrayList<MForm>(); + MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false); + input.setValue(100); + MStringInput strInput = new MStringInput("STRING-INPUT",false,(short)20); + strInput.setValue("TEST-VALUE"); + List<MInput<?>> list = new ArrayList<MInput<?>>(); + list.add(input); + list.add(strInput); + MForm form = new MForm("FORMNAME", list); + forms.add(form); + + MConnectionForms connectionForms1 = new MConnectionForms(forms); + MJobForms fromForm = null; + MJobForms toForm = null; + + if (supportedDirections.contains(Direction.FROM)) { + fromForm = new MJobForms(forms); + } + + if (supportedDirections.contains(Direction.TO)) { + toForm = new MJobForms(forms); + } + + return new MConnector("NAME", "CLASSNAME", "1.0", + connectionForms1, fromForm, toForm); + } + /** * Test for initialization */ @@ -65,47 +95,58 @@ public class TestMConnector { } } -// @Test -// public void testClone() { -// List<MForm> forms = new ArrayList<MForm>(); -// MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false); -// input.setValue(100); -// MStringInput strInput = new MStringInput("STRING-INPUT",false,(short)20); -// strInput.setValue("TEST-VALUE"); -// List<MInput<?>> list = new ArrayList<MInput<?>>(); -// list.add(input); -// list.add(strInput); -// MForm form = new MForm("FORMNAME", list); -// forms.add(form); -// MConnectionForms connectionForms1 = new MConnectionForms(forms); -// MJobForms jobform1 = new MJobForms(MJob.Type.EXPORT, forms); -// List<MJobForms> jobFormList = new ArrayList<MJobForms>(); -// jobFormList.add(jobform1); -// MConnector connector1 = new MConnector("NAME", "CLASSNAME", "1.0", -// connectionForms1, jobFormList); -// assertEquals("NAME", connector1.getUniqueName()); -// assertEquals("CLASSNAME", connector1.getClassName()); -// assertEquals("1.0", connector1.getVersion()); -// //Clone with values. Checking values copying after the cloning. But form values will be null -// MConnector clone1 = connector1.clone(true); -// assertEquals("NAME", clone1.getUniqueName()); -// assertEquals("CLASSNAME", clone1.getClassName()); -// assertEquals("1.0", clone1.getVersion()); -// MForm clonedForm1 = clone1.getConnectionForms().getForms().get(0); -// assertNull(clonedForm1.getInputs().get(0).getValue()); -// assertNull(clonedForm1.getInputs().get(1).getValue()); -// -// MForm clonedForm2 = clone1.getJobForms(MJob.Type.EXPORT).getForms().get(0); -// assertNull(clonedForm2.getInputs().get(0).getValue()); -// assertNull(clonedForm2.getInputs().get(1).getValue()); -// -// //Clone without values. Inputs value will be null after cloning. -// MConnector clone2 = connector1.clone(false); -// clonedForm1 = clone2.getConnectionForms().getForms().get(0); -// assertNull(clonedForm1.getInputs().get(0).getValue()); -// assertNull(clonedForm1.getInputs().get(1).getValue()); -// clonedForm2 = clone2.getJobForms(MJob.Type.EXPORT).getForms().get(0); -// assertNull(clonedForm2.getInputs().get(0).getValue()); -// assertNull(clonedForm2.getInputs().get(1).getValue()); -// } + @Test + public void testClone() { + MConnector connector1 = createConnector(Arrays.asList(Direction.FROM, Direction.TO)); + assertEquals("NAME", connector1.getUniqueName()); + assertEquals("CLASSNAME", connector1.getClassName()); + assertEquals("1.0", connector1.getVersion()); + //Clone with values. Checking values copying after the cloning. But form values will be null + MConnector clone1 = connector1.clone(true); + assertEquals("NAME", clone1.getUniqueName()); + assertEquals("CLASSNAME", clone1.getClassName()); + assertEquals("1.0", clone1.getVersion()); + MForm clonedForm1 = clone1.getConnectionForms().getForms().get(0); + assertNull(clonedForm1.getInputs().get(0).getValue()); + assertNull(clonedForm1.getInputs().get(1).getValue()); + + MForm clonedForm2 = clone1.getJobForms(Direction.FROM).getForms().get(0); + assertNull(clonedForm2.getInputs().get(0).getValue()); + assertNull(clonedForm2.getInputs().get(1).getValue()); + + MForm clonedForm3 = clone1.getJobForms(Direction.TO).getForms().get(0); + assertNull(clonedForm3.getInputs().get(0).getValue()); + assertNull(clonedForm3.getInputs().get(1).getValue()); + + //Clone without values. Inputs value will be null after cloning. + MConnector clone2 = connector1.clone(false); + clonedForm1 = clone2.getConnectionForms().getForms().get(0); + assertNull(clonedForm1.getInputs().get(0).getValue()); + assertNull(clonedForm1.getInputs().get(1).getValue()); + clonedForm2 = clone2.getJobForms(Direction.FROM).getForms().get(0); + assertNull(clonedForm2.getInputs().get(0).getValue()); + assertNull(clonedForm2.getInputs().get(1).getValue()); + clonedForm3 = clone2.getJobForms(Direction.TO).getForms().get(0); + assertNull(clonedForm3.getInputs().get(0).getValue()); + assertNull(clonedForm3.getInputs().get(1).getValue()); + } + + @Test + public void testGetSupportedDirections() { + MConnector connector = createConnector(Arrays.asList(Direction.FROM, Direction.TO)); + assertTrue(connector.getSupportedDirections().isDirectionSupported(Direction.FROM)); + assertTrue(connector.getSupportedDirections().isDirectionSupported(Direction.TO)); + + connector = createConnector(Arrays.asList(Direction.FROM)); + assertTrue(connector.getSupportedDirections().isDirectionSupported(Direction.FROM)); + assertFalse(connector.getSupportedDirections().isDirectionSupported(Direction.TO)); + + connector = createConnector(Arrays.asList(Direction.TO)); + assertFalse(connector.getSupportedDirections().isDirectionSupported(Direction.FROM)); + assertTrue(connector.getSupportedDirections().isDirectionSupported(Direction.TO)); + + connector = createConnector(Arrays.asList(new Direction[]{})); + assertFalse(connector.getSupportedDirections().isDirectionSupported(Direction.FROM)); + assertFalse(connector.getSupportedDirections().isDirectionSupported(Direction.TO)); + } } http://git-wip-us.apache.org/repos/asf/sqoop/blob/27fb31d4/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java b/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java index 8782209..6c10b54 100644 --- a/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java +++ b/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java @@ -98,15 +98,11 @@ public final class ConnectorHandler { if (connector.getSupportedDirections().contains(Direction.FROM)) { fromJobForms = new MJobForms(FormUtils.toForms( connector.getJobConfigurationClass(Direction.FROM))); - } else { - fromJobForms = new MJobForms(new ArrayList<MForm>()); } if (connector.getSupportedDirections().contains(Direction.TO)) { toJobForms = new MJobForms(FormUtils.toForms( connector.getJobConfigurationClass(Direction.TO))); - } else { - toJobForms = new MJobForms(new ArrayList<MForm>()); } MConnectionForms connectionForms = new MConnectionForms( http://git-wip-us.apache.org/repos/asf/sqoop/blob/27fb31d4/shell/src/main/java/org/apache/sqoop/shell/ShowConnectorFunction.java ---------------------------------------------------------------------- diff --git a/shell/src/main/java/org/apache/sqoop/shell/ShowConnectorFunction.java b/shell/src/main/java/org/apache/sqoop/shell/ShowConnectorFunction.java index bbfbb3f..50978ff 100644 --- a/shell/src/main/java/org/apache/sqoop/shell/ShowConnectorFunction.java +++ b/shell/src/main/java/org/apache/sqoop/shell/ShowConnectorFunction.java @@ -23,6 +23,8 @@ import java.util.List; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.OptionBuilder; +import org.apache.sqoop.common.Direction; +import org.apache.sqoop.common.SupportedDirections; import org.apache.sqoop.model.MConnector; import org.apache.sqoop.shell.core.Constants; import org.apache.sqoop.shell.utils.TableDisplayer; @@ -33,6 +35,8 @@ import static org.apache.sqoop.shell.utils.FormDisplayer.*; @SuppressWarnings("serial") public class ShowConnectorFunction extends SqoopFunction { + private static final char SUPPORTED_DIRECTIONS_SEPARATOR = '/'; + @SuppressWarnings("static-access") public ShowConnectorFunction() { this.addOption(OptionBuilder @@ -66,20 +70,23 @@ public class ShowConnectorFunction extends SqoopFunction { header.add(resourceString(Constants.RES_TABLE_HEADER_NAME)); header.add(resourceString(Constants.RES_TABLE_HEADER_VERSION)); header.add(resourceString(Constants.RES_TABLE_HEADER_CLASS)); + header.add(resourceString(Constants.RES_TABLE_HEADER_SUPPORTED_DIRECTIONS)); List<String> ids = new LinkedList<String>(); List<String> uniqueNames = new LinkedList<String>(); List<String> versions = new LinkedList<String>(); List<String> classes = new LinkedList<String>(); + List<String> supportedDirections = new LinkedList<String>(); for(MConnector connector : connectors) { ids.add(String.valueOf(connector.getPersistenceId())); uniqueNames.add(connector.getUniqueName()); versions.add(connector.getVersion()); classes.add(connector.getClassName()); + supportedDirections.add(getSupportedDirections(connector)); } - TableDisplayer.display(header, ids, uniqueNames, versions, classes); + TableDisplayer.display(header, ids, uniqueNames, versions, classes, supportedDirections); } private void showConnectors() { @@ -105,8 +112,34 @@ public class ShowConnectorFunction extends SqoopFunction { connector.getPersistenceId(), connector.getUniqueName(), connector.getClassName(), - connector.getVersion() + connector.getVersion(), + getSupportedDirections(connector) ); displayFormMetadataDetails(connector, client.getResourceBundle(connector.getPersistenceId())); } + + /** + * Creates a nicely formatted string for which directions are supported. + * Example: FROM/TO. + * @param connector + * @return String + */ + private String getSupportedDirections(MConnector connector) { + StringBuffer supportedDirectionsBuffer = new StringBuffer(); + SupportedDirections supportedDirections + = connector.getSupportedDirections(); + + if (supportedDirections.isDirectionSupported(Direction.FROM)) { + supportedDirectionsBuffer.append(Direction.FROM); + + if (supportedDirections.isDirectionSupported(Direction.TO)) { + supportedDirectionsBuffer.append(SUPPORTED_DIRECTIONS_SEPARATOR); + supportedDirectionsBuffer.append(Direction.TO); + } + } else if (supportedDirections.isDirectionSupported(Direction.TO)) { + supportedDirectionsBuffer.append(Direction.TO); + } + + return supportedDirectionsBuffer.toString(); + } } http://git-wip-us.apache.org/repos/asf/sqoop/blob/27fb31d4/shell/src/main/java/org/apache/sqoop/shell/core/Constants.java ---------------------------------------------------------------------- diff --git a/shell/src/main/java/org/apache/sqoop/shell/core/Constants.java b/shell/src/main/java/org/apache/sqoop/shell/core/Constants.java index efabc46..f0dc3a6 100644 --- a/shell/src/main/java/org/apache/sqoop/shell/core/Constants.java +++ b/shell/src/main/java/org/apache/sqoop/shell/core/Constants.java @@ -333,6 +333,8 @@ public class Constants { "table.header.version"; public static final String RES_TABLE_HEADER_CLASS = "table.header.class"; + public static final String RES_TABLE_HEADER_SUPPORTED_DIRECTIONS = + "table.header.supported_directions"; public static final String RES_TABLE_HEADER_CONNECTOR = "table.header.connector"; public static final String RES_TABLE_HEADER_FROM_CONNECTOR = http://git-wip-us.apache.org/repos/asf/sqoop/blob/27fb31d4/shell/src/main/resources/shell-resource.properties ---------------------------------------------------------------------- diff --git a/shell/src/main/resources/shell-resource.properties b/shell/src/main/resources/shell-resource.properties index 73a19e8..247ceae 100644 --- a/shell/src/main/resources/shell-resource.properties +++ b/shell/src/main/resources/shell-resource.properties @@ -137,8 +137,8 @@ show.prompt_display_all_connectors = Display all connectors show.prompt_display_connector_cid = Display the connector with cid show.connector_usage = Usage: show connector show.prompt_connectors_to_show = @|bold {0} connector(s) to show: |@ -show.prompt_connector_info = Connector with id {0}:\n Name: {1} \n \ -Class: {2}\n Version: {3} +show.prompt_connector_info = Connector with id {0}:\n Name: {1} \n \ +Class: {2}\n Version: {3}\n Supported Directions {4} show.framework_usage = Usage: show framework show.prompt_framework_opts = @|bold Framework specific options: |@\nPersistent id: {0} @@ -190,6 +190,7 @@ table.header.id = Id table.header.name = Name table.header.version = Version table.header.class = Class +table.header.supported_directions = Supported Directions table.header.connector = Connector table.header.connector.from = From Connector table.header.connector.to = To Connector
