SQOOP-1454: Sqoop2: From/To: Add client support for supported directions

(Abraham Elmahrek via Jarek Jarcec Cecho)
This commit is contained in:
Jarek Jarcec Cecho 2014-09-21 12:42:10 -07:00 коммит произвёл Abraham Elmahrek
Родитель 3d539dd4d7
Коммит 27fb31d42e
8 изменённых файлов: 226 добавлений и 51 удалений

Просмотреть файл

@ -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 @@ 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);
}
}

Просмотреть файл

@ -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 @@ 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));
}
}

Просмотреть файл

@ -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(

Просмотреть файл

@ -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();
}
}

Просмотреть файл

@ -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 =

Просмотреть файл

@ -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