hawq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nh...@apache.org
Subject incubator-hawq git commit: HAWQ-253. Separate pxf-service from pxf plugins
Date Thu, 28 Jan 2016 22:46:06 GMT
Repository: incubator-hawq
Updated Branches:
  refs/heads/master e22956c6f -> 1df504f4f


HAWQ-253. Separate pxf-service from pxf plugins

1. Move Utilities class from pxf-service to pxf-api package.
2. Split StringPassResolverTest to two unit test files - one testing functionality of StringPassResolver.setFields
    and the other testing the functionality of BridgeInputBuilder.makeInput.
3. Close stream in WritableResource using try-with-resources.


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/1df504f4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/1df504f4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/1df504f4

Branch: refs/heads/master
Commit: 1df504f4f27b4559ff32d64b80061a85835440fd
Parents: e22956c
Author: Noa Horn <nhorn@pivotal.io>
Authored: Thu Jan 28 14:45:51 2016 -0800
Committer: Noa Horn <nhorn@pivotal.io>
Committed: Thu Jan 28 14:45:51 2016 -0800

----------------------------------------------------------------------
 pxf/build.gradle                                |   4 +-
 .../hawq/pxf/api/utilities/Utilities.java       | 153 ++++++++++++++++++
 .../hawq/pxf/api/utilities/UtilitiesTest.java   | 117 ++++++++++++++
 .../pxf/plugins/hdfs/StringPassResolver.java    |   8 +-
 .../hawq/pxf/plugins/hdfs/WritableResolver.java |   2 +-
 .../plugins/hdfs/utilities/HdfsUtilities.java   |   2 +-
 .../plugins/hdfs/StringPassResolverTest.java    | 105 ++----------
 .../plugins/hive/HiveColumnarSerdeResolver.java |   3 +-
 .../hawq/pxf/plugins/hive/HiveResolver.java     |   3 +-
 .../hawq/pxf/service/FragmenterFactory.java     |   2 +-
 .../org/apache/hawq/pxf/service/ReadBridge.java |   2 +-
 .../apache/hawq/pxf/service/WriteBridge.java    |   2 +-
 .../pxf/service/rest/InvalidPathResource.java   |   3 +-
 .../hawq/pxf/service/rest/WritableResource.java |  10 +-
 .../hawq/pxf/service/utilities/Utilities.java   | 154 ------------------
 .../pxf/service/BridgeInputBuilderTest.java     | 159 +++++++++++++++++++
 .../pxf/service/utilities/UtilitiesTest.java    | 116 --------------
 17 files changed, 466 insertions(+), 379 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/build.gradle
----------------------------------------------------------------------
diff --git a/pxf/build.gradle b/pxf/build.gradle
index 0d260d4..cc913ec 100644
--- a/pxf/build.gradle
+++ b/pxf/build.gradle
@@ -237,9 +237,11 @@ project('pxf-service') {
 
 project('pxf-hdfs') {
     dependencies {
-        compile(project(':pxf-service'))
+        compile(project(':pxf-api'))
         compile 'org.apache.avro:avro-mapred:1.7.4'
         compile "org.apache.hadoop:hadoop-mapreduce-client-core:$hadoopVersion"
+        compile "org.apache.hadoop:hadoop-common:$hadoopVersion"
+        compile "org.apache.hadoop:hadoop-hdfs:$hadoopVersion"
     }
 
     ospackage {

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-api/src/main/java/org/apache/hawq/pxf/api/utilities/Utilities.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-api/src/main/java/org/apache/hawq/pxf/api/utilities/Utilities.java b/pxf/pxf-api/src/main/java/org/apache/hawq/pxf/api/utilities/Utilities.java
new file mode 100644
index 0000000..314583c
--- /dev/null
+++ b/pxf/pxf-api/src/main/java/org/apache/hawq/pxf/api/utilities/Utilities.java
@@ -0,0 +1,153 @@
+package org.apache.hawq.pxf.api.utilities;
+
+/*
+ * 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.
+ */
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Utilities class exposes helper method for PXF classes
+ */
+public class Utilities {
+    private static final Log LOG = LogFactory.getLog(Utilities.class);
+
+    /**
+     * Creates an object using the class name. The class name has to be a class
+     * located in the webapp's CLASSPATH.
+     *
+     * @param confClass the class of the metaData used to initialize the
+     *            instance
+     * @param className a class name to be initialized.
+     * @param metaData input data used to initialize the class
+     * @return Initialized instance of given className
+     * @throws Exception throws exception if classname was not found in
+     *             classpath, didn't have expected constructor or failed to be
+     *             instantiated
+     */
+    public static Object createAnyInstance(Class<?> confClass,
+                                           String className, InputData metaData)
+            throws Exception {
+
+        Class<?> cls = null;
+        try {
+            cls = Class.forName(className);
+        } catch (ClassNotFoundException e) {
+            // in case the class name uses the old "com.pivotal.pxf" package
+            // name, recommend using the new package "org.apache.hawq.pxf".
+            if (className.startsWith("com.pivotal.pxf")) {
+                throw new Exception(
+                        "Class "
+                                + className
+                                + " does not appear in classpath. "
+                                + "Plugins provided by PXF must start with \"org.apache.hawq.pxf\"",
+                        e.getCause());
+            } else {
+                throw e;
+            }
+        }
+
+        Constructor<?> con = cls.getConstructor(confClass);
+
+        return instantiate(con, metaData);
+    }
+
+    /**
+     * Creates an object using the class name with its default constructor. The
+     * class name has to be a class located in the webapp's CLASSPATH.
+     *
+     * @param className a class name to be initialized
+     * @return initialized instance of given className
+     * @throws Exception throws exception if classname was not found in
+     *             classpath, didn't have expected constructor or failed to be
+     *             instantiated
+     */
+    public static Object createAnyInstance(String className) throws Exception {
+        Class<?> cls = Class.forName(className);
+        Constructor<?> con = cls.getConstructor();
+        return instantiate(con);
+    }
+
+    private static Object instantiate(Constructor<?> con, Object... args)
+            throws Exception {
+        try {
+            return con.newInstance(args);
+        } catch (InvocationTargetException e) {
+            /*
+             * We are creating resolvers, accessors, fragmenters, etc. using the
+             * reflection framework. If for example, a resolver, during its
+             * instantiation - in the c'tor, will throw an exception, the
+             * Resolver's exception will reach the Reflection layer and there it
+             * will be wrapped inside an InvocationTargetException. Here we are
+             * above the Reflection layer and we need to unwrap the Resolver's
+             * initial exception and throw it instead of the wrapper
+             * InvocationTargetException so that our initial Exception text will
+             * be displayed in psql instead of the message:
+             * "Internal Server Error"
+             */
+            throw (e.getCause() != null) ? new Exception(e.getCause()) : e;
+        }
+    }
+
+    /**
+     * Transforms a byte array into a string of octal codes in the form
+     * \\xyz\\xyz
+     *
+     * We double escape each char because it is required in postgres bytea for
+     * some bytes. In the minimum all non-printables, backslash, null and single
+     * quote. Easier to just escape everything see
+     * http://www.postgresql.org/docs/9.0/static/datatype-binary.html
+     *
+     * Octal codes must be padded to 3 characters (001, 012)
+     *
+     * @param bytes bytes to escape
+     * @param sb octal codes of given bytes
+     */
+    public static void byteArrayToOctalString(byte[] bytes, StringBuilder sb) {
+        if ((bytes == null) || (sb == null)) {
+            return;
+        }
+
+        sb.ensureCapacity(sb.length()
+                + (bytes.length * 5 /* characters per byte */));
+        for (int b : bytes) {
+            sb.append(String.format("\\\\%03o", b & 0xff));
+        }
+    }
+
+    /**
+     * Replaces any non-alpha-numeric character with a '.'. This measure is used
+     * to prevent cross-site scripting (XSS) when an input string might include
+     * code or script. By removing all special characters and returning a
+     * censured string to the user this threat is avoided.
+     *
+     * @param input string to be masked
+     * @return masked string
+     */
+    public static String maskNonPrintables(String input) {
+        if (StringUtils.isEmpty(input)) {
+            return input;
+        }
+        return input.replaceAll("[^a-zA-Z0-9_:/-]", ".");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-api/src/test/java/org/apache/hawq/pxf/api/utilities/UtilitiesTest.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-api/src/test/java/org/apache/hawq/pxf/api/utilities/UtilitiesTest.java b/pxf/pxf-api/src/test/java/org/apache/hawq/pxf/api/utilities/UtilitiesTest.java
new file mode 100644
index 0000000..355ea42
--- /dev/null
+++ b/pxf/pxf-api/src/test/java/org/apache/hawq/pxf/api/utilities/UtilitiesTest.java
@@ -0,0 +1,117 @@
+package org.apache.hawq.pxf.api.utilities;
+
+/*
+ * 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.
+ */
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.hawq.pxf.api.utilities.InputData;
+import org.apache.hawq.pxf.api.utilities.Utilities;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({Class.class})
+public class UtilitiesTest {
+    @Test
+    public void byteArrayToOctalStringNull() throws Exception {
+        StringBuilder sb = null;
+        byte[] bytes = "nofink".getBytes();
+
+        Utilities.byteArrayToOctalString(bytes, sb);
+
+        assertNull(sb);
+
+        sb = new StringBuilder();
+        bytes = null;
+
+        Utilities.byteArrayToOctalString(bytes, sb);
+
+        assertEquals(0, sb.length());
+    }
+
+    @Test
+    public void byteArrayToOctalString() throws Exception {
+        String orig = "Have Narisha";
+        String octal = "Rash Rash Rash!";
+        String expected = orig + "\\\\122\\\\141\\\\163\\\\150\\\\040"
+                + "\\\\122\\\\141\\\\163\\\\150\\\\040"
+                + "\\\\122\\\\141\\\\163\\\\150\\\\041";
+        StringBuilder sb = new StringBuilder();
+        sb.append(orig);
+
+        Utilities.byteArrayToOctalString(octal.getBytes(), sb);
+
+        assertEquals(orig.length() + (octal.length() * 5), sb.length());
+        assertEquals(expected, sb.toString());
+    }
+
+    @Test
+    public void createAnyInstanceOldPackageName() throws Exception {
+
+        InputData metaData = mock(InputData.class);
+        String className = "com.pivotal.pxf.Lucy";
+        ClassNotFoundException exception = new ClassNotFoundException(className);
+        PowerMockito.mockStatic(Class.class);
+        when(Class.forName(className)).thenThrow(exception);
+
+        try {
+            Utilities.createAnyInstance(InputData.class,
+                    className, metaData);
+            fail("creating an instance should fail because the class doesn't exist in classpath");
+        } catch (Exception e) {
+            assertEquals(e.getClass(), Exception.class);
+            assertEquals(
+                    e.getMessage(),
+                    "Class " + className + " does not appear in classpath. "
+                    + "Plugins provided by PXF must start with \"org.apache.hawq.pxf\"");
+        }
+    }
+
+    @Test
+    public void maskNonPrintable() throws Exception {
+        String input = "";
+        String result = Utilities.maskNonPrintables(input);
+        assertEquals("", result);
+
+        input = null;
+        result = Utilities.maskNonPrintables(input);
+        assertEquals(null, result);
+
+        input = "Lucy in the sky";
+        result = Utilities.maskNonPrintables(input);
+        assertEquals("Lucy.in.the.sky", result);
+
+        input = "with <$$$@#$!000diamonds!!?!$#&%/>";
+        result = Utilities.maskNonPrintables(input);
+        assertEquals("with.........000diamonds......../.", result);
+
+        input = "http://www.beatles.com/info?query=whoisthebest";
+        result = Utilities.maskNonPrintables(input);
+        assertEquals("http://www.beatles.com/info.query.whoisthebest", result);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolver.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolver.java b/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolver.java
index a48e263..dc7d1d5 100644
--- a/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolver.java
+++ b/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolver.java
@@ -8,9 +8,9 @@ package org.apache.hawq.pxf.plugins.hdfs;
  * 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
@@ -35,8 +35,8 @@ import static org.apache.hawq.pxf.api.io.DataType.VARCHAR;
 
 /**
  * StringPassResolver handles "deserialization" and serialization of
- * String records. StringPassResolver implements IReadResolver and
- * IWriteResolver interfaces. Returns strings as-is.
+ * String records. StringPassResolver implements {@link ReadResolver} and
+ * {@link WriteResolver} interfaces. Returns strings as-is.
  */
 public class StringPassResolver extends Plugin implements ReadResolver, WriteResolver {
     // for write

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/WritableResolver.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/WritableResolver.java b/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/WritableResolver.java
index 89870c6..c758231 100644
--- a/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/WritableResolver.java
+++ b/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/WritableResolver.java
@@ -24,9 +24,9 @@ import org.apache.hawq.pxf.api.*;
 import org.apache.hawq.pxf.api.io.DataType;
 import org.apache.hawq.pxf.api.utilities.InputData;
 import org.apache.hawq.pxf.api.utilities.Plugin;
+import org.apache.hawq.pxf.api.utilities.Utilities;
 import org.apache.hawq.pxf.plugins.hdfs.utilities.RecordkeyAdapter;
 import org.apache.hawq.pxf.plugins.hdfs.utilities.DataSchemaException;
-import org.apache.hawq.pxf.service.utilities.Utilities;
 
 import static org.apache.hawq.pxf.plugins.hdfs.utilities.DataSchemaException.MessageFmt.*;
 

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/utilities/HdfsUtilities.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/utilities/HdfsUtilities.java b/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/utilities/HdfsUtilities.java
index aa8c4b4..59551a9 100644
--- a/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/utilities/HdfsUtilities.java
+++ b/pxf/pxf-hdfs/src/main/java/org/apache/hawq/pxf/plugins/hdfs/utilities/HdfsUtilities.java
@@ -20,10 +20,10 @@ package org.apache.hawq.pxf.plugins.hdfs.utilities;
  */
 
 
-import org.apache.hawq.pxf.service.utilities.Utilities;
 import org.apache.hawq.pxf.api.io.DataType;
 import org.apache.hawq.pxf.api.OneField;
 import org.apache.hawq.pxf.api.utilities.InputData;
+import org.apache.hawq.pxf.api.utilities.Utilities;
 import org.apache.avro.Schema;
 import org.apache.avro.file.DataFileReader;
 import org.apache.avro.generic.GenericDatumReader;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-hdfs/src/test/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolverTest.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-hdfs/src/test/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolverTest.java b/pxf/pxf-hdfs/src/test/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolverTest.java
index d03cec8..2e76962 100644
--- a/pxf/pxf-hdfs/src/test/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolverTest.java
+++ b/pxf/pxf-hdfs/src/test/java/org/apache/hawq/pxf/plugins/hdfs/StringPassResolverTest.java
@@ -24,36 +24,22 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
-import org.apache.commons.logging.LogFactory;
 import org.apache.hawq.pxf.api.OneField;
 import org.apache.hawq.pxf.api.OneRow;
-import org.apache.hawq.pxf.api.OutputFormat;
-import org.apache.hawq.pxf.service.BridgeInputBuilder;
-import org.apache.hawq.pxf.service.io.Text;
-import org.apache.hawq.pxf.service.utilities.ProtocolData;
+import org.apache.hawq.pxf.api.io.DataType;
+import org.apache.hawq.pxf.api.utilities.InputData;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({
-        Text.class,
-        BridgeInputBuilder.class,
-        ProtocolData.class,
-        LogFactory.class })
+
 public class StringPassResolverTest {
-    ProtocolData mockProtocolData;
+    InputData mockInputData;
 
     @Test
     /*
-     * Test the setFields method: small \n terminated input
+     * Test the setFields method: small input
      */
     public void testSetFields() throws Exception {
         StringPassResolver resolver = buildResolver();
@@ -68,84 +54,31 @@ public class StringPassResolverTest {
                 (int) 'o',
                 (int) '\n' };
 
-        DataInputStream inputStream = new DataInputStream(
-                new ByteArrayInputStream(data));
-        BridgeInputBuilder inputBuilder = new BridgeInputBuilder(
-                mockProtocolData);
-        List<OneField> record = inputBuilder.makeInput(inputStream);
+        List<OneField> record = Collections.singletonList(new OneField(DataType.BYTEA.getOID(),
+                Arrays.copyOfRange(data, 0, 5)));
 
         OneRow oneRow = resolver.setFields(record);
         verifyOneRow(oneRow, Arrays.copyOfRange(data, 0, 5));
 
-        record = inputBuilder.makeInput(inputStream);
+        record = Collections.singletonList(new OneField(DataType.BYTEA.getOID(),
+                Arrays.copyOfRange(data, 5, 8)));
+
         oneRow = resolver.setFields(record);
         verifyOneRow(oneRow, Arrays.copyOfRange(data, 5, 8));
     }
 
     @Test
     /*
-     * Test the setFields method: input > buffer size, \n terminated
-     */
-    public void testSetFieldsBigArray() throws Exception {
-
-        StringPassResolver resolver = buildResolver();
-
-        byte[] bigArray = new byte[2000];
-        for (int i = 0; i < 1999; ++i) {
-            bigArray[i] = (byte) (i % 10 + 30);
-        }
-        bigArray[1999] = (byte) '\n';
-
-        DataInputStream inputStream = new DataInputStream(
-                new ByteArrayInputStream(bigArray));
-        BridgeInputBuilder inputBuilder = new BridgeInputBuilder(
-                mockProtocolData);
-        List<OneField> record = inputBuilder.makeInput(inputStream);
-
-        OneRow oneRow = resolver.setFields(record);
-
-        verifyOneRow(oneRow, bigArray);
-    }
-
-    @Test
-    /*
-     * Test the setFields method: input > buffer size, no \n
+     * Test the setFields method: empty byte array
      */
-    public void testSetFieldsBigArrayNoNewLine() throws Exception {
-
-        StringPassResolver resolver = buildResolver();
-
-        byte[] bigArray = new byte[2000];
-        for (int i = 0; i < 2000; ++i) {
-            bigArray[i] = (byte) (i % 10 + 60);
-        }
-
-        DataInputStream inputStream = new DataInputStream(
-                new ByteArrayInputStream(bigArray));
-        BridgeInputBuilder inputBuilder = new BridgeInputBuilder(
-                mockProtocolData);
-        List<OneField> record = inputBuilder.makeInput(inputStream);
-
-        OneRow oneRow = resolver.setFields(record);
-
-        verifyOneRow(oneRow, bigArray);
-    }
-
-    @Test
-    /*
-     * Test the setFields method: empty stream (returns -1)
-     */
-    public void testSetFieldsEmptyStream() throws Exception {
+    public void testSetFieldsEmptyByteArray() throws Exception {
 
         StringPassResolver resolver = buildResolver();
 
         byte[] empty = new byte[0];
 
-        DataInputStream inputStream = new DataInputStream(
-                new ByteArrayInputStream(empty));
-        BridgeInputBuilder inputBuilder = new BridgeInputBuilder(
-                mockProtocolData);
-        List<OneField> record = inputBuilder.makeInput(inputStream);
+        List<OneField> record = Collections.singletonList(new OneField(DataType.BYTEA.getOID(),
+                                                          empty));
 
         OneRow oneRow = resolver.setFields(record);
 
@@ -156,12 +89,8 @@ public class StringPassResolverTest {
      * helpers functions
      */
     private StringPassResolver buildResolver() throws Exception {
-
-        mockProtocolData = mock(ProtocolData.class);
-        PowerMockito.when(mockProtocolData.outputFormat()).thenReturn(
-                OutputFormat.TEXT);
-
-        return new StringPassResolver(mockProtocolData);
+        mockInputData = mock(InputData.class);
+        return new StringPassResolver(mockInputData);
     }
 
     private void verifyOneRow(OneRow oneRow, byte[] expected) {

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveColumnarSerdeResolver.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveColumnarSerdeResolver.java b/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveColumnarSerdeResolver.java
index 0120d7b..d298bac 100644
--- a/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveColumnarSerdeResolver.java
+++ b/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveColumnarSerdeResolver.java
@@ -27,8 +27,7 @@ import org.apache.hawq.pxf.api.UnsupportedTypeException;
 import org.apache.hawq.pxf.api.io.DataType;
 import org.apache.hawq.pxf.api.utilities.ColumnDescriptor;
 import org.apache.hawq.pxf.api.utilities.InputData;
-import org.apache.hawq.pxf.service.utilities.Utilities;
-
+import org.apache.hawq.pxf.api.utilities.Utilities;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveResolver.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveResolver.java b/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveResolver.java
index 59245d0..2562d3d 100644
--- a/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveResolver.java
+++ b/pxf/pxf-hive/src/main/java/org/apache/hawq/pxf/plugins/hive/HiveResolver.java
@@ -23,9 +23,8 @@ import org.apache.hawq.pxf.api.*;
 import org.apache.hawq.pxf.api.io.DataType;
 import org.apache.hawq.pxf.api.utilities.InputData;
 import org.apache.hawq.pxf.api.utilities.Plugin;
+import org.apache.hawq.pxf.api.utilities.Utilities;
 import org.apache.hawq.pxf.plugins.hdfs.utilities.HdfsUtilities;
-import org.apache.hawq.pxf.service.utilities.Utilities;
-
 import org.apache.commons.lang.CharUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/FragmenterFactory.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/FragmenterFactory.java b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/FragmenterFactory.java
index 0e15093..c516d69 100644
--- a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/FragmenterFactory.java
+++ b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/FragmenterFactory.java
@@ -22,7 +22,7 @@ package org.apache.hawq.pxf.service;
 
 import org.apache.hawq.pxf.api.Fragmenter;
 import org.apache.hawq.pxf.api.utilities.InputData;
-import org.apache.hawq.pxf.service.utilities.Utilities;
+import org.apache.hawq.pxf.api.utilities.Utilities;
 
 /**
  * Factory class for creation of {@link Fragmenter} objects. The actual {@link Fragmenter} object is "hidden" behind

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/ReadBridge.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/ReadBridge.java b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/ReadBridge.java
index 0f3c968..01a95ab 100644
--- a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/ReadBridge.java
+++ b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/ReadBridge.java
@@ -25,9 +25,9 @@ import org.apache.hawq.pxf.api.ReadAccessor;
 import org.apache.hawq.pxf.api.ReadResolver;
 import org.apache.hawq.pxf.api.utilities.InputData;
 import org.apache.hawq.pxf.api.utilities.Plugin;
+import org.apache.hawq.pxf.api.utilities.Utilities;
 import org.apache.hawq.pxf.service.io.Writable;
 import org.apache.hawq.pxf.service.utilities.ProtocolData;
-import org.apache.hawq.pxf.service.utilities.Utilities;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/WriteBridge.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/WriteBridge.java b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/WriteBridge.java
index 80552af..c3ee731 100644
--- a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/WriteBridge.java
+++ b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/WriteBridge.java
@@ -23,9 +23,9 @@ package org.apache.hawq.pxf.service;
 import org.apache.hawq.pxf.api.*;
 import org.apache.hawq.pxf.api.utilities.InputData;
 import org.apache.hawq.pxf.api.utilities.Plugin;
+import org.apache.hawq.pxf.api.utilities.Utilities;
 import org.apache.hawq.pxf.service.io.Writable;
 import org.apache.hawq.pxf.service.utilities.ProtocolData;
-import org.apache.hawq.pxf.service.utilities.Utilities;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/InvalidPathResource.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/InvalidPathResource.java b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/InvalidPathResource.java
index 8e987f3..5a9f0d1 100644
--- a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/InvalidPathResource.java
+++ b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/InvalidPathResource.java
@@ -22,9 +22,10 @@ package org.apache.hawq.pxf.service.rest;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.hawq.pxf.service.utilities.Utilities;
+import org.apache.hawq.pxf.api.utilities.Utilities;
 
 import com.google.common.collect.ImmutableSet;
+
 import java.util.Arrays;
 import java.util.List;
 

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/WritableResource.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/WritableResource.java b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/WritableResource.java
index 70bec2a..d1dea5e 100644
--- a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/WritableResource.java
+++ b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/rest/WritableResource.java
@@ -37,11 +37,11 @@ import javax.ws.rs.core.Response;
 import org.apache.catalina.connector.ClientAbortException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hawq.pxf.api.utilities.Utilities;
 import org.apache.hawq.pxf.service.Bridge;
 import org.apache.hawq.pxf.service.WriteBridge;
 import org.apache.hawq.pxf.service.utilities.ProtocolData;
 import org.apache.hawq.pxf.service.utilities.SecuredHDFS;
-import org.apache.hawq.pxf.service.utilities.Utilities;
 
 /*
  * Running this resource manually:
@@ -150,11 +150,11 @@ public class WritableResource extends RestResource{
         // Open the output file
         bridge.beginIteration();
 
-        DataInputStream dataStream = new DataInputStream(inputStream);
-
         long totalWritten = 0;
 
-        try {
+        // dataStream will close automatically in the end of the try.
+        // inputStream is closed by dataStream.close().
+        try (DataInputStream dataStream = new DataInputStream(inputStream)) {
             while (bridge.setNext(dataStream)) {
                 ++totalWritten;
             }
@@ -163,8 +163,6 @@ public class WritableResource extends RestResource{
         } catch (Exception ex) {
             LOG.debug("totalWritten so far " + totalWritten + " to " + path);
             throw ex;
-        } finally {
-            inputStream.close();
         }
 
         String censuredPath = Utilities.maskNonPrintables(path);

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/utilities/Utilities.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/utilities/Utilities.java b/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/utilities/Utilities.java
deleted file mode 100644
index 8467734..0000000
--- a/pxf/pxf-service/src/main/java/org/apache/hawq/pxf/service/utilities/Utilities.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package org.apache.hawq.pxf.service.utilities;
-
-/*
- * 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.
- */
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hawq.pxf.api.utilities.InputData;
-
-/**
- * Utilities class exposes helper method for PXF classes
- */
-public class Utilities {
-    private static final Log LOG = LogFactory.getLog(Utilities.class);
-
-    /**
-     * Creates an object using the class name. The class name has to be a class
-     * located in the webapp's CLASSPATH.
-     *
-     * @param confClass the class of the metaData used to initialize the
-     *            instance
-     * @param className a class name to be initialized.
-     * @param metaData input data used to initialize the class
-     * @return Initialized instance of given className
-     * @throws Exception throws exception if classname was not found in
-     *             classpath, didn't have expected constructor or failed to be
-     *             instantiated
-     */
-    public static Object createAnyInstance(Class<?> confClass,
-                                           String className, InputData metaData)
-            throws Exception {
-
-        Class<?> cls = null;
-        try {
-            cls = Class.forName(className);
-        } catch (ClassNotFoundException e) {
-            // in case the class name uses the old "com.pivotal.pxf" package
-            // name, recommend using the new package "org.apache.hawq.pxf".
-            if (className.startsWith("com.pivotal.pxf")) {
-                throw new Exception(
-                        "Class "
-                                + className
-                                + " does not appear in classpath. "
-                                + "Plugins provided by PXF must start with \"org.apache.hawq.pxf\"",
-                        e.getCause());
-            } else {
-                throw e;
-            }
-        }
-
-        Constructor<?> con = cls.getConstructor(confClass);
-
-        return instantiate(con, metaData);
-    }
-
-    /**
-     * Creates an object using the class name with its default constructor. The
-     * class name has to be a class located in the webapp's CLASSPATH.
-     *
-     * @param className a class name to be initialized
-     * @return initialized instance of given className
-     * @throws Exception throws exception if classname was not found in
-     *             classpath, didn't have expected constructor or failed to be
-     *             instantiated
-     */
-    public static Object createAnyInstance(String className) throws Exception {
-        Class<?> cls = Class.forName(className);
-        Constructor<?> con = cls.getConstructor();
-        return instantiate(con);
-    }
-
-    private static Object instantiate(Constructor<?> con, Object... args)
-            throws Exception {
-        try {
-            return con.newInstance(args);
-        } catch (InvocationTargetException e) {
-            /*
-             * We are creating resolvers, accessors, fragmenters, etc. using the
-             * reflection framework. If for example, a resolver, during its
-             * instantiation - in the c'tor, will throw an exception, the
-             * Resolver's exception will reach the Reflection layer and there it
-             * will be wrapped inside an InvocationTargetException. Here we are
-             * above the Reflection layer and we need to unwrap the Resolver's
-             * initial exception and throw it instead of the wrapper
-             * InvocationTargetException so that our initial Exception text will
-             * be displayed in psql instead of the message:
-             * "Internal Server Error"
-             */
-            throw (e.getCause() != null) ? new Exception(e.getCause()) : e;
-        }
-    }
-
-    /**
-     * Transforms a byte array into a string of octal codes in the form
-     * \\xyz\\xyz
-     *
-     * We double escape each char because it is required in postgres bytea for
-     * some bytes. In the minimum all non-printables, backslash, null and single
-     * quote. Easier to just escape everything see
-     * http://www.postgresql.org/docs/9.0/static/datatype-binary.html
-     *
-     * Octal codes must be padded to 3 characters (001, 012)
-     *
-     * @param bytes bytes to escape
-     * @param sb octal codes of given bytes
-     */
-    public static void byteArrayToOctalString(byte[] bytes, StringBuilder sb) {
-        if ((bytes == null) || (sb == null)) {
-            return;
-        }
-
-        sb.ensureCapacity(sb.length()
-                + (bytes.length * 5 /* characters per byte */));
-        for (int b : bytes) {
-            sb.append(String.format("\\\\%03o", b & 0xff));
-        }
-    }
-
-    /**
-     * Replaces any non-alpha-numeric character with a '.'. This measure is used
-     * to prevent cross-site scripting (XSS) when an input string might include
-     * code or script. By removing all special characters and returning a
-     * censured string to the user this threat is avoided.
-     *
-     * @param input string to be masked
-     * @return masked string
-     */
-    public static String maskNonPrintables(String input) {
-        if (StringUtils.isEmpty(input)) {
-            return input;
-        }
-        return input.replaceAll("[^a-zA-Z0-9_:/-]", ".");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-service/src/test/java/org/apache/hawq/pxf/service/BridgeInputBuilderTest.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-service/src/test/java/org/apache/hawq/pxf/service/BridgeInputBuilderTest.java b/pxf/pxf-service/src/test/java/org/apache/hawq/pxf/service/BridgeInputBuilderTest.java
new file mode 100644
index 0000000..2668ef3
--- /dev/null
+++ b/pxf/pxf-service/src/test/java/org/apache/hawq/pxf/service/BridgeInputBuilderTest.java
@@ -0,0 +1,159 @@
+package org.apache.hawq.pxf.service;
+
+/*
+ * 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.
+ */
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.hawq.pxf.api.OneField;
+import org.apache.hawq.pxf.api.OutputFormat;
+import org.apache.hawq.pxf.api.io.DataType;
+import org.apache.hawq.pxf.service.utilities.ProtocolData;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+public class BridgeInputBuilderTest {
+    ProtocolData mockProtocolData;
+    BridgeInputBuilder inputBuilder;
+    DataInputStream inputStream;
+
+    @Test
+    /*
+     * Test makeInput method: small \n terminated input
+     */
+    public void makeInput() throws Exception {
+
+        byte[] data = new byte[] {
+                (int) 'a',
+                (int) 'b',
+                (int) 'c',
+                (int) 'd',
+                (int) '\n',
+                (int) 'n',
+                (int) 'o',
+                (int) '\n' };
+
+        prepareInput(data);
+
+        List<OneField> record = inputBuilder.makeInput(inputStream);
+
+        verifyRecord(record, Arrays.copyOfRange(data, 0, 5));
+
+        record = inputBuilder.makeInput(inputStream);
+        verifyRecord(record, Arrays.copyOfRange(data, 5, 8));
+    }
+
+    @Test
+    /*
+     * Test the makeInput method: input > buffer size, \n terminated
+     */
+    public void makeInputBigArray() throws Exception {
+
+        byte[] bigArray = new byte[2000];
+        for (int i = 0; i < 1999; ++i) {
+            bigArray[i] = (byte) (i % 10 + 30);
+        }
+        bigArray[1999] = (byte) '\n';
+
+        prepareInput(bigArray);
+
+        List<OneField> record = inputBuilder.makeInput(inputStream);
+
+        verifyRecord(record, bigArray);
+    }
+
+    @Test
+    /*
+     * Test the makeInput method: input > buffer size, no \n
+     */
+    public void makeInputBigArrayNoNewLine() throws Exception {
+
+        byte[] bigArray = new byte[2000];
+        for (int i = 0; i < 2000; ++i) {
+            bigArray[i] = (byte) (i % 10 + 60);
+        }
+
+        prepareInput(bigArray);
+
+        List<OneField> record = inputBuilder.makeInput(inputStream);
+
+        verifyRecord(record, bigArray);
+    }
+
+    @Test
+    /*
+     * Test the makeInput method: empty stream (returns -1)
+     */
+    public void makeInputEmptyStream() throws Exception {
+
+        byte[] empty = new byte[0];
+
+        prepareInput(empty);
+
+        List<OneField> record = inputBuilder.makeInput(inputStream);
+
+        verifyRecord(record, empty);
+    }
+
+    /*
+     * helpers functions
+     */
+
+    @After
+    public void cleanUp() throws IOException {
+        if (inputStream != null) {
+            inputStream.close();
+        }
+    }
+
+    private void prepareInput(byte[] data) throws Exception {
+        mockProtocolData = mock(ProtocolData.class);
+        PowerMockito.when(mockProtocolData.outputFormat()).thenReturn(
+                OutputFormat.TEXT);
+        inputBuilder = new BridgeInputBuilder(
+                mockProtocolData);
+        inputStream = new DataInputStream(
+                new ByteArrayInputStream(data));
+    }
+
+    private void verifyRecord(List<OneField> record, byte[] expected) {
+        assertEquals(record.size(), 1);
+
+        OneField field = record.get(0);
+        assertEquals(field.type, DataType.BYTEA.getOID());
+
+        byte[] bytes = (byte[]) field.val;
+        byte[] result = Arrays.copyOfRange(bytes, 0, bytes.length);
+        assertEquals(result.length, expected.length);
+        assertTrue(Arrays.equals(result, expected));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1df504f4/pxf/pxf-service/src/test/java/org/apache/hawq/pxf/service/utilities/UtilitiesTest.java
----------------------------------------------------------------------
diff --git a/pxf/pxf-service/src/test/java/org/apache/hawq/pxf/service/utilities/UtilitiesTest.java b/pxf/pxf-service/src/test/java/org/apache/hawq/pxf/service/utilities/UtilitiesTest.java
deleted file mode 100644
index 0afb4e2..0000000
--- a/pxf/pxf-service/src/test/java/org/apache/hawq/pxf/service/utilities/UtilitiesTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.apache.hawq.pxf.service.utilities;
-
-/*
- * 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.
- */
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.apache.hawq.pxf.api.utilities.InputData;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({Class.class})
-public class UtilitiesTest {
-    @Test
-    public void byteArrayToOctalStringNull() throws Exception {
-        StringBuilder sb = null;
-        byte[] bytes = "nofink".getBytes();
-
-        Utilities.byteArrayToOctalString(bytes, sb);
-
-        assertNull(sb);
-
-        sb = new StringBuilder();
-        bytes = null;
-
-        Utilities.byteArrayToOctalString(bytes, sb);
-
-        assertEquals(0, sb.length());
-    }
-
-    @Test
-    public void byteArrayToOctalString() throws Exception {
-        String orig = "Have Narisha";
-        String octal = "Rash Rash Rash!";
-        String expected = orig + "\\\\122\\\\141\\\\163\\\\150\\\\040"
-                + "\\\\122\\\\141\\\\163\\\\150\\\\040"
-                + "\\\\122\\\\141\\\\163\\\\150\\\\041";
-        StringBuilder sb = new StringBuilder();
-        sb.append(orig);
-
-        Utilities.byteArrayToOctalString(octal.getBytes(), sb);
-
-        assertEquals(orig.length() + (octal.length() * 5), sb.length());
-        assertEquals(expected, sb.toString());
-    }
-
-    @Test
-    public void createAnyInstanceOldPackageName() throws Exception {
-
-        InputData metaData = mock(InputData.class);
-        String className = "com.pivotal.pxf.Lucy";
-        ClassNotFoundException exception = new ClassNotFoundException(className);
-        PowerMockito.mockStatic(Class.class);
-        when(Class.forName(className)).thenThrow(exception);
-
-        try {
-            Utilities.createAnyInstance(InputData.class,
-                    className, metaData);
-            fail("creating an instance should fail because the class doesn't exist in classpath");
-        } catch (Exception e) {
-            assertEquals(e.getClass(), Exception.class);
-            assertEquals(
-                    e.getMessage(),
-                    "Class " + className + " does not appear in classpath. "
-                    + "Plugins provided by PXF must start with \"org.apache.hawq.pxf\"");
-        }
-    }
-
-    @Test
-    public void maskNonPrintable() throws Exception {
-        String input = "";
-        String result = Utilities.maskNonPrintables(input);
-        assertEquals("", result);
-
-        input = null;
-        result = Utilities.maskNonPrintables(input);
-        assertEquals(null, result);
-
-        input = "Lucy in the sky";
-        result = Utilities.maskNonPrintables(input);
-        assertEquals("Lucy.in.the.sky", result);
-
-        input = "with <$$$@#$!000diamonds!!?!$#&%/>";
-        result = Utilities.maskNonPrintables(input);
-        assertEquals("with.........000diamonds......../.", result);
-
-        input = "http://www.beatles.com/info?query=whoisthebest";
-        result = Utilities.maskNonPrintables(input);
-        assertEquals("http://www.beatles.com/info.query.whoisthebest", result);
-    }
-}


Mime
View raw message