You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by el...@apache.org on 2017/09/14 22:46:35 UTC
[2/4] phoenix git commit: PHOENIX-4189 Introduce a class that wraps
the Map of primary key data
PHOENIX-4189 Introduce a class that wraps the Map of primary key data
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/9b0c0af1
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/9b0c0af1
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/9b0c0af1
Branch: refs/heads/4.x-HBase-1.2
Commit: 9b0c0af11a04ab91dde68e3f961c9a543c1b0fd5
Parents: 5ccf8ef
Author: Josh Elser <el...@apache.org>
Authored: Sat Sep 9 00:00:57 2017 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Thu Sep 14 18:30:40 2017 -0400
----------------------------------------------------------------------
.../org/apache/phoenix/hive/PhoenixRowKey.java | 17 ++--
.../org/apache/phoenix/hive/PrimaryKeyData.java | 88 ++++++++++++++++++++
.../hive/util/PhoenixStorageHandlerUtil.java | 9 +-
.../apache/phoenix/hive/PrimaryKeyDataTest.java | 79 ++++++++++++++++++
4 files changed, 175 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/9b0c0af1/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRowKey.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRowKey.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRowKey.java
index c4cbb2c..a963fba 100644
--- a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRowKey.java
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRowKey.java
@@ -17,15 +17,12 @@
*/
package org.apache.phoenix.hive;
-import com.google.common.collect.Maps;
import org.apache.hadoop.hive.ql.io.RecordIdentifier;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Map;
@@ -35,33 +32,29 @@ import java.util.Map;
public class PhoenixRowKey extends RecordIdentifier {
- private Map<String, Object> rowKeyMap = Maps.newHashMap();
+ private PrimaryKeyData rowKeyMap = PrimaryKeyData.EMPTY;
public PhoenixRowKey() {
}
public void setRowKeyMap(Map<String, Object> rowKeyMap) {
- this.rowKeyMap = rowKeyMap;
+ this.rowKeyMap = new PrimaryKeyData(rowKeyMap);
}
@Override
public void write(DataOutput dataOutput) throws IOException {
super.write(dataOutput);
- try (ObjectOutputStream oos = new ObjectOutputStream((OutputStream) dataOutput)) {
- oos.writeObject(rowKeyMap);
- oos.flush();
- }
+ rowKeyMap.serialize((OutputStream) dataOutput);
}
- @SuppressWarnings("unchecked")
@Override
public void readFields(DataInput dataInput) throws IOException {
super.readFields(dataInput);
- try (ObjectInputStream ois = new ObjectInputStream((InputStream) dataInput)) {
- rowKeyMap = (Map<String, Object>) ois.readObject();
+ try {
+ rowKeyMap = PrimaryKeyData.deserialize((InputStream) dataInput);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/9b0c0af1/phoenix-hive/src/main/java/org/apache/phoenix/hive/PrimaryKeyData.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PrimaryKeyData.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PrimaryKeyData.java
new file mode 100644
index 0000000..b5e9dd9
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PrimaryKeyData.java
@@ -0,0 +1,88 @@
+/*
+ * 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.phoenix.hive;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidClassException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Wrapper around the primary key data for Hive.
+ */
+public class PrimaryKeyData implements Serializable{
+ public static final PrimaryKeyData EMPTY = new PrimaryKeyData(Collections.<String,Object> emptyMap());
+ private static final long serialVersionUID = 1L;
+
+ // Based on https://www.ibm.com/developerworks/library/se-lookahead/. Prevents unexpected
+ // deserialization of other objects of an unexpected class.
+ private static class LookAheadObjectInputStream extends ObjectInputStream {
+ public LookAheadObjectInputStream(InputStream in) throws IOException {
+ super(in);
+ }
+
+ @Override
+ protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
+ if (!desc.getName().equals(PrimaryKeyData.class.getName()) &&
+ !desc.getName().startsWith("java.lang.") &&
+ !desc.getName().startsWith("java.util.") &&
+ !desc.getName().startsWith("java.sql.")) {
+ throw new InvalidClassException(desc.getName(), "Expected an instance of PrimaryKeyData");
+ }
+ return super.resolveClass(desc);
+ }
+ }
+
+ private final HashMap<String,Object> data;
+
+ public PrimaryKeyData(Map<String,Object> data) {
+ if (data instanceof HashMap) {
+ this.data = (HashMap<String,Object>) data;
+ } else {
+ this.data = new HashMap<>(Objects.requireNonNull(data));
+ }
+ }
+
+ public HashMap<String,Object> getData() {
+ return data;
+ }
+
+ public void serialize(OutputStream output) throws IOException {
+ try (ObjectOutputStream oos = new ObjectOutputStream(output)) {
+ oos.writeObject(this);
+ oos.flush();
+ }
+ }
+
+ public static PrimaryKeyData deserialize(InputStream input) throws IOException, ClassNotFoundException {
+ try (LookAheadObjectInputStream ois = new LookAheadObjectInputStream((InputStream) input)) {
+ Object obj = ois.readObject();
+ if (obj instanceof PrimaryKeyData) {
+ return (PrimaryKeyData) obj;
+ }
+ throw new InvalidClassException(obj == null ? "null" : obj.getClass().getName(), "Disallowed serialized class");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/9b0c0af1/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixStorageHandlerUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixStorageHandlerUtil.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixStorageHandlerUtil.java
index 1dc8545..19c26e5 100644
--- a/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixStorageHandlerUtil.java
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixStorageHandlerUtil.java
@@ -21,7 +21,6 @@ import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.ObjectInputStream;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.net.InetAddress;
@@ -51,6 +50,7 @@ import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.net.DNS;
+import org.apache.phoenix.hive.PrimaryKeyData;
import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
import org.apache.phoenix.hive.ql.index.IndexSearchCondition;
import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
@@ -256,16 +256,13 @@ public class PhoenixStorageHandlerUtil {
}
public static Map<?, ?> toMap(byte[] serialized) {
- Map<?, ?> resultMap = null;
ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
- try (ObjectInputStream ois = new ObjectInputStream(bais)) {
- resultMap = (Map<?, ?>) ois.readObject();
+ try {
+ return PrimaryKeyData.deserialize(bais).getData();
} catch (ClassNotFoundException | IOException e) {
throw new RuntimeException(e);
}
-
- return resultMap;
}
public static String getOptionsValue(Options options) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/9b0c0af1/phoenix-hive/src/test/java/org/apache/phoenix/hive/PrimaryKeyDataTest.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/test/java/org/apache/phoenix/hive/PrimaryKeyDataTest.java b/phoenix-hive/src/test/java/org/apache/phoenix/hive/PrimaryKeyDataTest.java
new file mode 100644
index 0000000..3b2634f
--- /dev/null
+++ b/phoenix-hive/src/test/java/org/apache/phoenix/hive/PrimaryKeyDataTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.phoenix.hive;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+
+import org.junit.Test;
+
+public class PrimaryKeyDataTest {
+ private static class Disallowed implements Serializable {
+ private static final long serialVersionUID = 1L;
+ }
+
+ private byte[] serialize(Object o) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ oos.writeObject(o);
+ }
+ return baos.toByteArray();
+ }
+
+ @Test
+ public void testSerde() throws Exception {
+ HashMap<String,Object> data = new HashMap<>();
+ data.put("one", 1);
+ data.put("two", "two");
+ data.put("three", 3);
+
+ PrimaryKeyData pkData = new PrimaryKeyData(data);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ pkData.serialize(baos);
+
+ PrimaryKeyData pkCopy = PrimaryKeyData.deserialize(new ByteArrayInputStream(baos.toByteArray()));
+ assertEquals(data, pkCopy.getData());
+ }
+
+ @Test
+ public void testDisallowedDeserialization() throws Exception {
+ byte[] serializedMap = serialize(new HashMap<String,Object>());
+ byte[] serializedClass = serialize(new Disallowed());
+ byte[] serializedString = serialize("asdf");
+
+ try {
+ PrimaryKeyData.deserialize(new ByteArrayInputStream(serializedMap));
+ fail("Expected an InvalidClassException");
+ } catch (InvalidClassException e) {}
+ try {
+ PrimaryKeyData.deserialize(new ByteArrayInputStream(serializedClass));
+ fail("Expected an InvalidClassException");
+ } catch (InvalidClassException e) {}
+ try {
+ PrimaryKeyData.deserialize(new ByteArrayInputStream(serializedString));
+ fail("Expected an InvalidClassException");
+ } catch (InvalidClassException e) {}
+ }
+}