org.kiji.rest.TestKijiRestEntityId.java Source code

Java tutorial

Introduction

Here is the source code for org.kiji.rest.TestKijiRestEntityId.java

Source

/**
 * (c) Copyright 2013 WibiData, Inc.
 *
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * Licensed 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.kiji.rest;

import static org.junit.Assert.*;

import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import org.apache.commons.codec.binary.Hex;
import org.apache.hadoop.hbase.util.Bytes;
import org.codehaus.jettison.json.JSONObject;

import org.junit.Test;

import org.kiji.rest.representations.KijiRestEntityId;
import org.kiji.schema.EntityId;
import org.kiji.schema.EntityIdFactory;
import org.kiji.schema.avro.TableLayoutDesc;
import org.kiji.schema.layout.KijiTableLayout;
import org.kiji.schema.layout.KijiTableLayouts;
import org.kiji.schema.tools.ToolUtils;
import org.kiji.schema.util.Hasher;

public class TestKijiRestEntityId {
    // Unusual UTF-16 string with Cyrillic, Imperial Phoenician, etc.
    private static final String UNUSUAL_STRING_EID = "abcde\b\fa0?";
    private static final String SINGLE_COMPONENT_EID = String.format("[%s]", JSONObject.quote(UNUSUAL_STRING_EID));

    @Test
    public void testShouldWorkWithRKFRawLayout() throws Exception {
        final TableLayoutDesc desc = KijiTableLayouts.getLayout("org/kiji/rest/layouts/rkf_raw.json");
        final KijiTableLayout layout = KijiTableLayout.newLayout(desc);
        final EntityIdFactory factory = EntityIdFactory.getFactory(layout);
        final byte[] rowKey = Bytes.toBytes(UNUSUAL_STRING_EID);
        final EntityId originalEid = factory.getEntityIdFromHBaseRowKey(rowKey);
        final KijiRestEntityId restEid1 = KijiRestEntityId.create(originalEid, layout);
        final KijiRestEntityId restEid2 = KijiRestEntityId
                .create(String.format("hbase=%s", Bytes.toStringBinary(rowKey)));
        final KijiRestEntityId restEid3 = KijiRestEntityId
                .create(String.format("hbase_hex=%s", new String(Hex.encodeHex((rowKey)))));

        // Resolved entity id should match origin entity id.
        assertEquals(originalEid, restEid1.resolve(layout));
        assertEquals(originalEid, restEid2.resolve(layout));
        assertEquals(originalEid, restEid3.resolve(layout));
    }

    @Test
    public void testShouldWorkWithRKFHashedLayout() throws Exception {
        final TableLayoutDesc desc = KijiTableLayouts.getLayout("org/kiji/rest/layouts/rkf_hashed.json");
        final KijiTableLayout layout = KijiTableLayout.newLayout(desc);
        final EntityIdFactory factory = EntityIdFactory.getFactory(layout);

        // Byte array representations of row keys should work.
        final byte[] rowKey = Bytes.toBytes(UNUSUAL_STRING_EID);
        final EntityId originalEid = factory.getEntityIdFromHBaseRowKey(rowKey);
        final KijiRestEntityId restEid1 = KijiRestEntityId.create(originalEid, layout);
        final KijiRestEntityId restEid2 = KijiRestEntityId
                .create(String.format("hbase=%s", Bytes.toStringBinary(rowKey)));
        final KijiRestEntityId restEid3 = KijiRestEntityId
                .create(String.format("hbase_hex=%s", new String(Hex.encodeHex((rowKey)))));

        // Resolved entity id should match origin entity id.
        assertEquals(originalEid, restEid1.resolve(layout));
        assertEquals(originalEid, restEid2.resolve(layout));
        assertEquals(originalEid, restEid3.resolve(layout));

        // Component representation of entities should work.
        final KijiRestEntityId restEid4 = KijiRestEntityId.createFromUrl(SINGLE_COMPONENT_EID, layout);
        final EntityId resolvedEid = restEid4.resolve(layout);
        final String recoveredComponent = Bytes.toString(Bytes
                .toBytesBinary(resolvedEid.toShellString().substring(ToolUtils.KIJI_ROW_KEY_SPEC_PREFIX.length())));
        assertEquals(UNUSUAL_STRING_EID, recoveredComponent);
        assertEquals(resolvedEid, restEid4.resolve(layout));
    }

    @Test
    public void testShouldWorkWithRKFHashPrefixedLayout() throws Exception {
        final TableLayoutDesc desc = KijiTableLayouts.getLayout("org/kiji/rest/layouts/rkf_hashprefixed.json");
        final KijiTableLayout layout = KijiTableLayout.newLayout(desc);
        final EntityIdFactory factory = EntityIdFactory.getFactory(layout);

        // Byte array representations of row keys should work.
        // Prepend appropriate hashed prefix to UNUSUAL_STRING_EID.
        final byte[] rowKey = Bytes.toBytes(UNUSUAL_STRING_EID);
        final byte[] hash = Hasher.hash(Bytes.toBytes(UNUSUAL_STRING_EID));
        final byte[] hbaseRowKey = new byte[rowKey.length + 2];
        System.arraycopy(hash, 0, hbaseRowKey, 0, 2);
        System.arraycopy(rowKey, 0, hbaseRowKey, 2, rowKey.length);
        final EntityId originalEid = factory.getEntityIdFromHBaseRowKey(hbaseRowKey);
        final KijiRestEntityId restEid1 = KijiRestEntityId.create(originalEid, layout);
        final KijiRestEntityId restEid2 = KijiRestEntityId
                .create(String.format("hbase=%s", Bytes.toStringBinary(hbaseRowKey)));
        final KijiRestEntityId restEid3 = KijiRestEntityId
                .create(String.format("hbase_hex=%s", new String(Hex.encodeHex((hbaseRowKey)))));

        // Resolved entity id should match origin entity id.
        assertEquals(originalEid, restEid1.resolve(layout));
        assertEquals(originalEid, restEid2.resolve(layout));
        assertEquals(originalEid, restEid3.resolve(layout));

        // Component representation of entities should work.
        final KijiRestEntityId restEid4 = KijiRestEntityId.createFromUrl(SINGLE_COMPONENT_EID, layout);
        final EntityId resolvedEid = restEid4.resolve(layout);
        final String recoveredComponent = Bytes.toString(Bytes
                .toBytesBinary(resolvedEid.toShellString().substring(ToolUtils.KIJI_ROW_KEY_SPEC_PREFIX.length())));
        assertEquals(UNUSUAL_STRING_EID, recoveredComponent);
        assertEquals(resolvedEid, restEid4.resolve(layout));
    }

    @Test
    public void testShouldWorkWithRKF2RawLayout() throws Exception {
        final TableLayoutDesc desc = KijiTableLayouts.getLayout("org/kiji/rest/layouts/rkf2_raw.json");
        final KijiTableLayout layout = KijiTableLayout.newLayout(desc);
        final EntityIdFactory factory = EntityIdFactory.getFactory(layout);
        final byte[] rowKey = Bytes.toBytes(UNUSUAL_STRING_EID);
        final EntityId originalEid = factory.getEntityIdFromHBaseRowKey(rowKey);
        final KijiRestEntityId restEid1 = KijiRestEntityId.create(originalEid, layout);
        final KijiRestEntityId restEid2 = KijiRestEntityId
                .create(String.format("hbase=%s", Bytes.toStringBinary(rowKey)));
        final KijiRestEntityId restEid3 = KijiRestEntityId
                .create(String.format("hbase_hex=%s", new String(Hex.encodeHex((rowKey)))));

        // Resolved entity id should match origin entity id.
        assertEquals(originalEid, restEid1.resolve(layout));
        assertEquals(originalEid, restEid2.resolve(layout));
        assertEquals(originalEid, restEid3.resolve(layout));
    }

    @Test
    public void testShouldWorkWithRKF2SuppressedLayout() throws Exception {
        final TableLayoutDesc desc = KijiTableLayouts.getLayout("org/kiji/rest/layouts/rkf2_suppressed.json");
        final KijiTableLayout layout = KijiTableLayout.newLayout(desc);

        // Construct complex entity id.
        final String eidString = String.format("[%s,%s,%s,%d,%d]", JSONObject.quote(UNUSUAL_STRING_EID),
                JSONObject.quote(UNUSUAL_STRING_EID), JSONObject.quote(UNUSUAL_STRING_EID), Integer.MIN_VALUE,
                Long.MAX_VALUE);
        final EntityId originalEid = ToolUtils.createEntityIdFromUserInputs(eidString, layout);
        final KijiRestEntityId restEid1 = KijiRestEntityId.create(originalEid, layout);
        final KijiRestEntityId restEid2 = KijiRestEntityId.createFromUrl(eidString, layout);
        final KijiRestEntityId restEid3 = KijiRestEntityId
                .create(String.format("hbase_hex=%s", new String(Hex.encodeHex((originalEid.getHBaseRowKey())))));
        final KijiRestEntityId restEid4 = KijiRestEntityId
                .create(String.format("hbase=%s", Bytes.toStringBinary(originalEid.getHBaseRowKey())));

        // Resolved entity id should match origin entity id.
        assertEquals(originalEid, restEid1.resolve(layout));
        assertEquals(originalEid, restEid2.resolve(layout));
        assertEquals(originalEid, restEid3.resolve(layout));
        assertEquals(originalEid, restEid4.resolve(layout));
    }

    @Test
    public void testShouldWorkWithRKF2FormattedLayout() throws Exception {
        final TableLayoutDesc desc = KijiTableLayouts.getLayout("org/kiji/rest/layouts/rkf2_suppressed.json");
        final KijiTableLayout layout = KijiTableLayout.newLayout(desc);

        // Construct complex entity id.
        final String eidString = String.format("[%s,%s,%s,%d,%d]", JSONObject.quote(UNUSUAL_STRING_EID),
                JSONObject.quote(UNUSUAL_STRING_EID), JSONObject.quote(UNUSUAL_STRING_EID), Integer.MIN_VALUE,
                Long.MAX_VALUE);
        final EntityId originalEid = ToolUtils.createEntityIdFromUserInputs(eidString, layout);
        final KijiRestEntityId restEid1 = KijiRestEntityId.create(originalEid, layout);
        final KijiRestEntityId restEid2 = KijiRestEntityId.createFromUrl(eidString, layout);
        final KijiRestEntityId restEid3 = KijiRestEntityId
                .create(String.format("hbase_hex=%s", new String(Hex.encodeHex((originalEid.getHBaseRowKey())))));
        final KijiRestEntityId restEid4 = KijiRestEntityId
                .create(String.format("hbase=%s", Bytes.toStringBinary(originalEid.getHBaseRowKey())));
        final EntityId toolUtilsEid = ToolUtils.createEntityIdFromUserInputs(eidString, layout);

        // Resolved entity id should match origin entity id.
        assertEquals(originalEid, restEid1.resolve(layout));
        assertEquals(originalEid, restEid2.resolve(layout));
        assertEquals(originalEid, restEid3.resolve(layout));
        assertEquals(originalEid, restEid4.resolve(layout));
        assertEquals(toolUtilsEid, restEid4.resolve(layout));
    }

    @Test
    public void testShouldCreateListsOfEntityIds() throws Exception {
        final TableLayoutDesc desc = KijiTableLayouts.getLayout("org/kiji/rest/layouts/rkf_hashprefixed.json");
        final KijiTableLayout layout = KijiTableLayout.newLayout(desc);
        final EntityIdFactory factory = EntityIdFactory.getFactory(layout);
        final byte[] rowKey = Bytes.toBytes(UNUSUAL_STRING_EID);
        final EntityId originalEid = factory.getEntityIdFromHBaseRowKey(rowKey);

        // test the creation of entity ids from raw hbase rowkey
        final KijiRestEntityId restEid1 = KijiRestEntityId.createFromUrl(
                String.format("hbase_hex=%s", new String(Hex.encodeHex(originalEid.getHBaseRowKey()))), layout);
        final KijiRestEntityId restEid2 = KijiRestEntityId.createFromUrl(
                String.format("hbase=%s", Bytes.toStringBinary(originalEid.getHBaseRowKey())), layout);

        final JsonNodeFactory jsonNodeFactory = new JsonNodeFactory(true);
        final JsonNode hbaseHexStringNode = jsonNodeFactory
                .textNode(String.format("hbase_hex=%s", new String(Hex.encodeHex(originalEid.getHBaseRowKey()))));
        final JsonNode hbaseBinaryStringNode = jsonNodeFactory
                .textNode(String.format("hbase_hex=%s", new String(Hex.encodeHex(originalEid.getHBaseRowKey()))));
        ArrayNode hbaseListNode = jsonNodeFactory.arrayNode();
        hbaseListNode.add(hbaseHexStringNode);
        hbaseListNode.add(hbaseBinaryStringNode);

        final List<KijiRestEntityId> restEidList1 = KijiRestEntityId.createListFromUrl(hbaseListNode.toString(),
                layout);

        assertEquals(restEid1.resolve(layout), restEidList1.get(0).resolve(layout));
        assertEquals(restEid2.resolve(layout), restEidList1.get(1).resolve(layout));

        // test the creation of entity ids from various json strings
        final KijiRestEntityId restEid3 = KijiRestEntityId.createFromUrl("[\"Hello\",\"World\"]", layout);
        final List<KijiRestEntityId> restEidList3 = KijiRestEntityId.createListFromUrl("[[\"Hello\",\"World\"]]",
                layout);
        final KijiRestEntityId restEid4 = KijiRestEntityId.createFromUrl("[[],\"World\"]", layout);
        final List<KijiRestEntityId> restEidList4 = KijiRestEntityId
                .createListFromUrl("[[[],\"World\"],[\"Hello\",\"World\"]]", layout);

        assertEquals(restEid3.resolve(layout), restEidList3.get(0).resolve(layout));
        assertEquals(restEid4.getStringEntityId(), restEidList4.get(0).getStringEntityId());
        assertEquals(1, restEidList3.size());
        assertEquals(2, restEidList4.size());
    }

    @Test
    public void testIntegerComponentsShouldBePromotableToLong() throws Exception {
        final TableLayoutDesc desc = KijiTableLayouts.getLayout("org/kiji/rest/layouts/rkf2_suppressed.json");
        final KijiTableLayout layout = KijiTableLayout.newLayout(desc);

        // Construct complex entity id.
        final String eidString = String.format("[%s,%s,%s,%d,%d]", JSONObject.quote(UNUSUAL_STRING_EID),
                JSONObject.quote(UNUSUAL_STRING_EID), JSONObject.quote(UNUSUAL_STRING_EID), 0, 0); // Promote this component.
        final KijiRestEntityId restEid = KijiRestEntityId.createFromUrl(eidString, layout);
        assertTrue(restEid.getComponents()[4] instanceof Long);
    }

    @Test
    public void testLongComponentsShouldNotComplain() throws Exception {
        final TableLayoutDesc desc = KijiTableLayouts.getLayout("org/kiji/rest/layouts/rkf2_suppressed.json");
        final KijiTableLayout layout = KijiTableLayout.newLayout(desc);

        // Construct complex entity id.
        final String eidString = String.format("[%s,%s,%s,%d,%d]", JSONObject.quote(UNUSUAL_STRING_EID),
                JSONObject.quote(UNUSUAL_STRING_EID), JSONObject.quote(UNUSUAL_STRING_EID), 0, Long.MAX_VALUE); // Long component of interest.
        final KijiRestEntityId restEid = KijiRestEntityId.createFromUrl(eidString, layout);
        assertTrue(restEid.getComponents()[4] instanceof Long);
    }
}