mirror of
https://github.com/apache/sqoop.git
synced 2025-05-10 22:13:07 +08:00
SQOOP-1454: Sqoop2: From/To: Add client support for supported directions
(Abraham Elmahrek via Jarek Jarcec Cecho)
This commit is contained in:
parent
3d539dd4d7
commit
27fb31d42e
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@
|
|||||||
import org.apache.sqoop.common.Direction;
|
import org.apache.sqoop.common.Direction;
|
||||||
import org.apache.sqoop.common.DirectionError;
|
import org.apache.sqoop.common.DirectionError;
|
||||||
import org.apache.sqoop.common.SqoopException;
|
import org.apache.sqoop.common.SqoopException;
|
||||||
|
import org.apache.sqoop.common.SupportedDirections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connector metadata.
|
* Connector metadata.
|
||||||
@ -139,4 +140,9 @@ public String getVersion() {
|
|||||||
public void setVersion(String version) {
|
public void setVersion(String version) {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SupportedDirections getSupportedDirections() {
|
||||||
|
return new SupportedDirections(this.getJobForms(Direction.FROM) != null,
|
||||||
|
this.getJobForms(Direction.TO) != null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -20,8 +20,10 @@
|
|||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.sqoop.common.Direction;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,6 +31,34 @@
|
|||||||
*/
|
*/
|
||||||
public class TestMConnector {
|
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
|
* Test for initialization
|
||||||
*/
|
*/
|
||||||
@ -65,47 +95,58 @@ public void testInitialization() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
// public void testClone() {
|
public void testClone() {
|
||||||
// List<MForm> forms = new ArrayList<MForm>();
|
MConnector connector1 = createConnector(Arrays.asList(Direction.FROM, Direction.TO));
|
||||||
// MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false);
|
assertEquals("NAME", connector1.getUniqueName());
|
||||||
// input.setValue(100);
|
assertEquals("CLASSNAME", connector1.getClassName());
|
||||||
// MStringInput strInput = new MStringInput("STRING-INPUT",false,(short)20);
|
assertEquals("1.0", connector1.getVersion());
|
||||||
// strInput.setValue("TEST-VALUE");
|
//Clone with values. Checking values copying after the cloning. But form values will be null
|
||||||
// List<MInput<?>> list = new ArrayList<MInput<?>>();
|
MConnector clone1 = connector1.clone(true);
|
||||||
// list.add(input);
|
assertEquals("NAME", clone1.getUniqueName());
|
||||||
// list.add(strInput);
|
assertEquals("CLASSNAME", clone1.getClassName());
|
||||||
// MForm form = new MForm("FORMNAME", list);
|
assertEquals("1.0", clone1.getVersion());
|
||||||
// forms.add(form);
|
MForm clonedForm1 = clone1.getConnectionForms().getForms().get(0);
|
||||||
// MConnectionForms connectionForms1 = new MConnectionForms(forms);
|
assertNull(clonedForm1.getInputs().get(0).getValue());
|
||||||
// MJobForms jobform1 = new MJobForms(MJob.Type.EXPORT, forms);
|
assertNull(clonedForm1.getInputs().get(1).getValue());
|
||||||
// List<MJobForms> jobFormList = new ArrayList<MJobForms>();
|
|
||||||
// jobFormList.add(jobform1);
|
MForm clonedForm2 = clone1.getJobForms(Direction.FROM).getForms().get(0);
|
||||||
// MConnector connector1 = new MConnector("NAME", "CLASSNAME", "1.0",
|
assertNull(clonedForm2.getInputs().get(0).getValue());
|
||||||
// connectionForms1, jobFormList);
|
assertNull(clonedForm2.getInputs().get(1).getValue());
|
||||||
// assertEquals("NAME", connector1.getUniqueName());
|
|
||||||
// assertEquals("CLASSNAME", connector1.getClassName());
|
MForm clonedForm3 = clone1.getJobForms(Direction.TO).getForms().get(0);
|
||||||
// assertEquals("1.0", connector1.getVersion());
|
assertNull(clonedForm3.getInputs().get(0).getValue());
|
||||||
// //Clone with values. Checking values copying after the cloning. But form values will be null
|
assertNull(clonedForm3.getInputs().get(1).getValue());
|
||||||
// MConnector clone1 = connector1.clone(true);
|
|
||||||
// assertEquals("NAME", clone1.getUniqueName());
|
//Clone without values. Inputs value will be null after cloning.
|
||||||
// assertEquals("CLASSNAME", clone1.getClassName());
|
MConnector clone2 = connector1.clone(false);
|
||||||
// assertEquals("1.0", clone1.getVersion());
|
clonedForm1 = clone2.getConnectionForms().getForms().get(0);
|
||||||
// MForm clonedForm1 = clone1.getConnectionForms().getForms().get(0);
|
assertNull(clonedForm1.getInputs().get(0).getValue());
|
||||||
// assertNull(clonedForm1.getInputs().get(0).getValue());
|
assertNull(clonedForm1.getInputs().get(1).getValue());
|
||||||
// assertNull(clonedForm1.getInputs().get(1).getValue());
|
clonedForm2 = clone2.getJobForms(Direction.FROM).getForms().get(0);
|
||||||
//
|
assertNull(clonedForm2.getInputs().get(0).getValue());
|
||||||
// MForm clonedForm2 = clone1.getJobForms(MJob.Type.EXPORT).getForms().get(0);
|
assertNull(clonedForm2.getInputs().get(1).getValue());
|
||||||
// assertNull(clonedForm2.getInputs().get(0).getValue());
|
clonedForm3 = clone2.getJobForms(Direction.TO).getForms().get(0);
|
||||||
// assertNull(clonedForm2.getInputs().get(1).getValue());
|
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);
|
@Test
|
||||||
// assertNull(clonedForm1.getInputs().get(0).getValue());
|
public void testGetSupportedDirections() {
|
||||||
// assertNull(clonedForm1.getInputs().get(1).getValue());
|
MConnector connector = createConnector(Arrays.asList(Direction.FROM, Direction.TO));
|
||||||
// clonedForm2 = clone2.getJobForms(MJob.Type.EXPORT).getForms().get(0);
|
assertTrue(connector.getSupportedDirections().isDirectionSupported(Direction.FROM));
|
||||||
// assertNull(clonedForm2.getInputs().get(0).getValue());
|
assertTrue(connector.getSupportedDirections().isDirectionSupported(Direction.TO));
|
||||||
// assertNull(clonedForm2.getInputs().get(1).getValue());
|
|
||||||
// }
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,15 +98,11 @@ public ConnectorHandler(URL configFileUrl) {
|
|||||||
if (connector.getSupportedDirections().contains(Direction.FROM)) {
|
if (connector.getSupportedDirections().contains(Direction.FROM)) {
|
||||||
fromJobForms = new MJobForms(FormUtils.toForms(
|
fromJobForms = new MJobForms(FormUtils.toForms(
|
||||||
connector.getJobConfigurationClass(Direction.FROM)));
|
connector.getJobConfigurationClass(Direction.FROM)));
|
||||||
} else {
|
|
||||||
fromJobForms = new MJobForms(new ArrayList<MForm>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connector.getSupportedDirections().contains(Direction.TO)) {
|
if (connector.getSupportedDirections().contains(Direction.TO)) {
|
||||||
toJobForms = new MJobForms(FormUtils.toForms(
|
toJobForms = new MJobForms(FormUtils.toForms(
|
||||||
connector.getJobConfigurationClass(Direction.TO)));
|
connector.getJobConfigurationClass(Direction.TO)));
|
||||||
} else {
|
|
||||||
toJobForms = new MJobForms(new ArrayList<MForm>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MConnectionForms connectionForms = new MConnectionForms(
|
MConnectionForms connectionForms = new MConnectionForms(
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.OptionBuilder;
|
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.model.MConnector;
|
||||||
import org.apache.sqoop.shell.core.Constants;
|
import org.apache.sqoop.shell.core.Constants;
|
||||||
import org.apache.sqoop.shell.utils.TableDisplayer;
|
import org.apache.sqoop.shell.utils.TableDisplayer;
|
||||||
@ -33,6 +35,8 @@
|
|||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class ShowConnectorFunction extends SqoopFunction {
|
public class ShowConnectorFunction extends SqoopFunction {
|
||||||
|
private static final char SUPPORTED_DIRECTIONS_SEPARATOR = '/';
|
||||||
|
|
||||||
@SuppressWarnings("static-access")
|
@SuppressWarnings("static-access")
|
||||||
public ShowConnectorFunction() {
|
public ShowConnectorFunction() {
|
||||||
this.addOption(OptionBuilder
|
this.addOption(OptionBuilder
|
||||||
@ -66,20 +70,23 @@ private void showSummary() {
|
|||||||
header.add(resourceString(Constants.RES_TABLE_HEADER_NAME));
|
header.add(resourceString(Constants.RES_TABLE_HEADER_NAME));
|
||||||
header.add(resourceString(Constants.RES_TABLE_HEADER_VERSION));
|
header.add(resourceString(Constants.RES_TABLE_HEADER_VERSION));
|
||||||
header.add(resourceString(Constants.RES_TABLE_HEADER_CLASS));
|
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> ids = new LinkedList<String>();
|
||||||
List<String> uniqueNames = new LinkedList<String>();
|
List<String> uniqueNames = new LinkedList<String>();
|
||||||
List<String> versions = new LinkedList<String>();
|
List<String> versions = new LinkedList<String>();
|
||||||
List<String> classes = new LinkedList<String>();
|
List<String> classes = new LinkedList<String>();
|
||||||
|
List<String> supportedDirections = new LinkedList<String>();
|
||||||
|
|
||||||
for(MConnector connector : connectors) {
|
for(MConnector connector : connectors) {
|
||||||
ids.add(String.valueOf(connector.getPersistenceId()));
|
ids.add(String.valueOf(connector.getPersistenceId()));
|
||||||
uniqueNames.add(connector.getUniqueName());
|
uniqueNames.add(connector.getUniqueName());
|
||||||
versions.add(connector.getVersion());
|
versions.add(connector.getVersion());
|
||||||
classes.add(connector.getClassName());
|
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() {
|
private void showConnectors() {
|
||||||
@ -105,8 +112,34 @@ private void displayConnector(MConnector connector) {
|
|||||||
connector.getPersistenceId(),
|
connector.getPersistenceId(),
|
||||||
connector.getUniqueName(),
|
connector.getUniqueName(),
|
||||||
connector.getClassName(),
|
connector.getClassName(),
|
||||||
connector.getVersion()
|
connector.getVersion(),
|
||||||
|
getSupportedDirections(connector)
|
||||||
);
|
);
|
||||||
displayFormMetadataDetails(connector, client.getResourceBundle(connector.getPersistenceId()));
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,6 +333,8 @@ public class Constants {
|
|||||||
"table.header.version";
|
"table.header.version";
|
||||||
public static final String RES_TABLE_HEADER_CLASS =
|
public static final String RES_TABLE_HEADER_CLASS =
|
||||||
"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 =
|
public static final String RES_TABLE_HEADER_CONNECTOR =
|
||||||
"table.header.connector";
|
"table.header.connector";
|
||||||
public static final String RES_TABLE_HEADER_FROM_CONNECTOR =
|
public static final String RES_TABLE_HEADER_FROM_CONNECTOR =
|
||||||
|
@ -138,7 +138,7 @@ show.prompt_display_connector_cid = Display the connector with cid
|
|||||||
show.connector_usage = Usage: show connector
|
show.connector_usage = Usage: show connector
|
||||||
show.prompt_connectors_to_show = @|bold {0} connector(s) to show: |@
|
show.prompt_connectors_to_show = @|bold {0} connector(s) to show: |@
|
||||||
show.prompt_connector_info = Connector with id {0}:\n Name: {1} \n \
|
show.prompt_connector_info = Connector with id {0}:\n Name: {1} \n \
|
||||||
Class: {2}\n Version: {3}
|
Class: {2}\n Version: {3}\n Supported Directions {4}
|
||||||
|
|
||||||
show.framework_usage = Usage: show framework
|
show.framework_usage = Usage: show framework
|
||||||
show.prompt_framework_opts = @|bold Framework specific options: |@\nPersistent id: {0}
|
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.name = Name
|
||||||
table.header.version = Version
|
table.header.version = Version
|
||||||
table.header.class = Class
|
table.header.class = Class
|
||||||
|
table.header.supported_directions = Supported Directions
|
||||||
table.header.connector = Connector
|
table.header.connector = Connector
|
||||||
table.header.connector.from = From Connector
|
table.header.connector.from = From Connector
|
||||||
table.header.connector.to = To Connector
|
table.header.connector.to = To Connector
|
||||||
|
Loading…
Reference in New Issue
Block a user