org.apache.ignite.GridTestIoUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ignite.GridTestIoUtils.java

Source

/*
 * 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.ignite;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.Externalizable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.Serializable;
import java.util.Arrays;
import org.apache.commons.io.IOUtils;
import org.apache.ignite.marshaller.Marshaller;
import org.jetbrains.annotations.Nullable;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

/**
 * IO test utilities.
 */
public final class GridTestIoUtils {
    /**
     * Serializes a given object into byte array.
     *
     * @param obj Object to serialize.
     * @return Byte array containing serialized object.
     * @throws IOException If serialization failed.
     */
    public static byte[] serializeJdk(Object obj) throws IOException {
        ByteArrayOutputStream byteOut = null;

        ObjectOutputStream objOut = null;

        try {
            // Allocate half of kilobyte to avoid very small resizings.
            byteOut = new ByteArrayOutputStream(512);

            objOut = new ObjectOutputStream(byteOut);

            // Make sure that we serialize only task, without
            // class loader.
            objOut.writeObject(obj);

            objOut.flush();

            return byteOut.toByteArray();
        } finally {
            close(objOut);
            close(byteOut);
        }
    }

    /**
     * Deserializes passed in bytes using provided class loader.
     *
     * @param <T> Type of result object.
     * @param bytes Object bytes to deserialize.
     * @return Deserialized object.
     * @throws IOException If deserialization failed.
     * @throws ClassNotFoundException If deserialization failed.
     */
    @SuppressWarnings({ "unchecked" })
    public static <T extends Serializable> T deserializeJdk(byte[] bytes)
            throws IOException, ClassNotFoundException {
        ObjectInputStream in = null;

        try {
            in = new ObjectInputStream(new ByteArrayInputStream(bytes));

            return (T) in.readObject();
        } finally {
            close(in);
        }
    }

    /**
     * Deserializes passed in bytes using provided class loader.
     *
     * @param <T> Type of result object.
     * @param bytes Object bytes to deserialize.
     * @param clsLdr Class loader.
     * @return Deserialized object.
     * @throws IOException If deserialization failed.
     * @throws ClassNotFoundException If deserialization failed.
     */
    @SuppressWarnings({ "unchecked" })
    public static <T> T deserializeJdk(byte[] bytes, final ClassLoader clsLdr)
            throws IOException, ClassNotFoundException {
        ObjectInputStream in = null;

        try {
            in = new ObjectInputStream(new ByteArrayInputStream(bytes)) {
                @Override
                protected Class<?> resolveClass(ObjectStreamClass desc) throws ClassNotFoundException {
                    return clsLdr.loadClass(desc.getName());
                }
            };

            return (T) in.readObject();
        } finally {
            close(in);
        }
    }

    /**
     * @param <T> Type of result object.
     * @param obj Object to marshal/unmarshal.
     * @param marshaller Marshaller to use for serialization.
     * @return The same object, but passed through marshaller: obj->marshal->buf->unmarshal->copy.
     * @throws Exception If failed.
     */
    @SuppressWarnings("unchecked")
    public static <T> T externalize(Externalizable obj, Marshaller marshaller) throws Exception {
        assert marshaller != null;

        byte[] buf = marshaller.marshal(obj);

        // Sleep to make sure that clock advances (necessary for some tests)
        Thread.sleep(10);

        return (T) marshaller.unmarshal(buf, obj.getClass().getClassLoader());
    }

    /**
     * Validate streams generate the same output.
     *
     * @param expIn Expected input stream.
     * @param actIn Actual input stream.
     * @param expSize Expected size of the streams.
     * @throws IOException In case of any IO exception.
     */
    public static void assertEqualStreams(InputStream expIn, InputStream actIn, @Nullable Long expSize)
            throws IOException {
        int bufSize = 2345;
        byte buf1[] = new byte[bufSize];
        byte buf2[] = new byte[bufSize];
        long pos = 0;

        while (true) {
            int i1 = actIn.read(buf1, 0, bufSize);

            int i2;

            if (i1 == -1) // Expects EOF?
                i2 = expIn.read(buf2, 0, 1); // Try to read at least 1 byte guaranted by stream's API.
            else
                IOUtils.readFully(expIn, buf2, 0, i2 = i1); // Read the same bytes count as from actual stream.

            if (i1 != i2)
                fail("Expects the same data [pos=" + pos + ", i1=" + i1 + ", i2=" + i2 + ']');

            if (i1 == -1)
                break; // EOF

            // i1 == bufSize => compare buffers.
            // i1 <  bufSize => Compare part of buffers, rest of buffers are equal from previous iteration.
            assertTrue("Expects the same data [pos=" + pos + ", i1=" + i1 + ", i2=" + i2 + ']',
                    Arrays.equals(buf1, buf2));

            pos += i1;
        }

        if (expSize != null)
            assertEquals(expSize.longValue(), pos);
    }

    /**
     * Gets short value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     */
    public static short getShortByByteLE(byte[] arr) {
        return getShortByByteLE(arr, 0);
    }

    /**
     * Gets short value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     * @param off Offset.
     */
    public static short getShortByByteLE(byte[] arr, int off) {
        return (short) ((arr[off] & 0xff) | arr[off + 1] << 8);
    }

    /**
     * Gets char value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     */
    public static char getCharByByteLE(byte[] arr) {
        return getCharByByteLE(arr, 0);
    }

    /**
     * Gets char value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     * @param off Offset.
     */
    public static char getCharByByteLE(byte[] arr, int off) {
        return (char) ((arr[off] & 0xff) | arr[off + 1] << 8);
    }

    /**
     * Gets integer value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     */
    public static int getIntByByteLE(byte[] arr) {
        return getIntByByteLE(arr, 0);
    }

    /**
     * Gets integer value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     * @param off Offset.
     */
    public static int getIntByByteLE(byte[] arr, int off) {
        return ((int) arr[off] & 0xff) | ((int) arr[off + 1] & 0xff) << 8 | ((int) arr[off + 2] & 0xff) << 16
                | ((int) arr[off + 3] & 0xff) << 24;
    }

    /**
     * Gets long value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     */
    public static long getLongByByteLE(byte[] arr) {
        return getLongByByteLE(arr, 0);
    }

    /**
     * Gets long value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     * @param off Offset.
     */
    public static long getLongByByteLE(byte[] arr, int off) {
        return ((long) arr[off] & 0xff) | ((long) arr[off + 1] & 0xff) << 8 | ((long) arr[off + 2] & 0xff) << 16
                | ((long) arr[off + 3] & 0xff) << 24 | ((long) arr[off + 4] & 0xff) << 32
                | ((long) arr[off + 5] & 0xff) << 40 | ((long) arr[off + 6] & 0xff) << 48
                | ((long) arr[off + 7] & 0xff) << 56;
    }

    /**
     * Gets float value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     */
    public static float getFloatByByteLE(byte[] arr) {
        return getFloatByByteLE(arr, 0);
    }

    /**
     * Gets float value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     * @param off Offset.
     */
    public static float getFloatByByteLE(byte[] arr, int off) {
        return Float.intBitsToFloat(getIntByByteLE(arr, off));
    }

    /**
     * Gets double value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     */
    public static double getDoubleByByteLE(byte[] arr) {
        return getDoubleByByteLE(arr, 0);
    }

    /**
     * Gets double value from byte array assuming that value stored in little-endian byte order.
     *
     * @param arr Byte array.
     * @param off Offset.
     */
    public static double getDoubleByByteLE(byte[] arr, int off) {
        return Double.longBitsToDouble(getLongByByteLE(arr, off));
    }

    /**
     * Closes resource.
     *
     * @param c Resource
     * @throws IOException If failed to close resource.
     */
    private static void close(Closeable c) throws IOException {
        if (c != null)
            c.close();
    }

    /**
     * Ensure singleton.
     */
    private GridTestIoUtils() {
        // No-op.
    }
}