Package org.apache.cassandra

Source Code of org.apache.cassandra.MutationTest$Insert

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

import java.io.IOException;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.cassandra.client.RingCache;
import org.apache.cassandra.dht.RandomPartitioner;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.thrift.*;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.WrappedRunnable;
import org.apache.thrift.TException;

import org.apache.cassandra.CassandraServiceController.Failure;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;

public class MutationTest extends TestBase
{
    private static final Logger logger = LoggerFactory.getLogger(MutationTest.class);

    @Test
    public void testInsert() throws Exception
    {
        List<InetAddress> hosts = controller.getHosts();
        final String keyspace = "TestInsert";
        addKeyspace(keyspace, 3);
        Cassandra.Client client = controller.createClient(hosts.get(0));
        client.set_keyspace(keyspace);

        ByteBuffer key = newKey();

        insert(client, key, "Standard1", "c1", "v1", 0, ConsistencyLevel.ONE);
        insert(client, key, "Standard1", "c2", "v2", 0, ConsistencyLevel.ONE);

        // block until the column is available
        new Get(client, "Standard1", key).name("c1").value("v1").perform(ConsistencyLevel.ONE);
        new Get(client, "Standard1", key).name("c2").value("v2").perform(ConsistencyLevel.ONE);

        List<ColumnOrSuperColumn> coscs = get_slice(client, key, "Standard1", ConsistencyLevel.ONE);
        assertColumnEqual("c1", "v1", 0, coscs.get(0).column);
        assertColumnEqual("c2", "v2", 0, coscs.get(1).column);
    }

    @Test
    public void testWriteAllReadOne() throws Exception
    {
        List<InetAddress> hosts = controller.getHosts();
        Cassandra.Client client = controller.createClient(hosts.get(0));

        final String keyspace = "TestWriteAllReadOne";
        addKeyspace(keyspace, 3);
        client.set_keyspace(keyspace);

        ByteBuffer key = newKey();

        insert(client, key, "Standard1", "c1", "v1", 0, ConsistencyLevel.ALL);
        // should be instantly available
        assertColumnEqual("c1", "v1", 0, getColumn(client, key, "Standard1", "c1", ConsistencyLevel.ONE));

        List<InetAddress> endpoints = endpointsForKey(hosts.get(0), key, keyspace);
        InetAddress coordinator = nonEndpointForKey(hosts.get(0), key, keyspace);
        Failure failure = controller.failHosts(endpoints.subList(1, endpoints.size()));

        try {
            client = controller.createClient(coordinator);
            client.set_keyspace(keyspace);

            new Get(client, "Standard1", key).name("c1").value("v1")
                .perform(ConsistencyLevel.ONE);

            new Insert(client, "Standard1", key).name("c3").value("v3")
                .expecting(UnavailableException.class).perform(ConsistencyLevel.ALL);
        } finally {
            failure.resolve();
            Thread.sleep(10000);
        }
    }

    @Test
    public void testWriteQuorumReadQuorum() throws Exception
    {
        List<InetAddress> hosts = controller.getHosts();
        Cassandra.Client client = controller.createClient(hosts.get(0));

        final String keyspace = "TestWriteQuorumReadQuorum";
        addKeyspace(keyspace, 3);
        client.set_keyspace(keyspace);

        ByteBuffer key = newKey();

        // with quorum-1 nodes up
        List<InetAddress> endpoints = endpointsForKey(hosts.get(0), key, keyspace);
        InetAddress coordinator = nonEndpointForKey(hosts.get(0), key, keyspace);
        Failure failure = controller.failHosts(endpoints.subList(1, endpoints.size())); //kill all but one nodes

        client = controller.createClient(coordinator);
        client.set_keyspace(keyspace);
        try {
            new Insert(client, "Standard1", key).name("c1").value("v1")
                .expecting(UnavailableException.class).perform(ConsistencyLevel.QUORUM);
        } finally {
            failure.resolve();
        }

        // with all nodes up
        new Insert(client, "Standard1", key).name("c2").value("v2").perform(ConsistencyLevel.QUORUM);

        failure = controller.failHosts(endpoints.get(0));
        try {
            new Get(client, "Standard1", key).name("c2").value("v2").perform(ConsistencyLevel.QUORUM);
        } finally {
            failure.resolve();
            Thread.sleep(10000);
        }
    }

    @Test
    public void testWriteOneReadAll() throws Exception
    {
        List<InetAddress> hosts = controller.getHosts();
        Cassandra.Client client = controller.createClient(hosts.get(0));

        final String keyspace = "TestWriteOneReadAll";
        addKeyspace(keyspace, 3);
        client.set_keyspace(keyspace);

        ByteBuffer key = newKey();

        List<InetAddress> endpoints = endpointsForKey(hosts.get(0), key, keyspace);
        InetAddress coordinator = nonEndpointForKey(hosts.get(0), key, keyspace);
        client = controller.createClient(coordinator);
        client.set_keyspace(keyspace);

        insert(client, key, "Standard1", "c1", "v1", 0, ConsistencyLevel.ONE);
        assertColumnEqual("c1", "v1", 0, getColumn(client, key, "Standard1", "c1", ConsistencyLevel.ALL));

        // with each of HH, read repair and proactive repair:
            // with one node up
            // write with one (success)
            // read with all (failure)
            // bring nodes up
            // repair
            // read with all (success)

        Failure failure = controller.failHosts(endpoints);
        try {
            new Insert(client, "Standard1", key).name("c2").value("v2")
                .expecting(UnavailableException.class).perform(ConsistencyLevel.ONE);
        } finally {
            failure.resolve();
        }
    }

    protected void insert(Cassandra.Client client, ByteBuffer key, String cf, String name, String value, long timestamp, ConsistencyLevel cl)
        throws InvalidRequestException, UnavailableException, TimedOutException, TException
    {
        Column col = new Column(
             ByteBufferUtil.bytes(name),
             ByteBufferUtil.bytes(value),
             timestamp
             );
        client.insert(key, new ColumnParent(cf), col, cl);
    }

    protected Column getColumn(Cassandra.Client client, ByteBuffer key, String cf, String col, ConsistencyLevel cl)
        throws InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException
    {
        ColumnPath cpath = new ColumnPath(cf);
        cpath.setColumn(col.getBytes());
        return client.get(key, cpath, cl).column;
    }

    protected class Get extends RetryingAction
    {
        public Get(Cassandra.Client client, String cf, ByteBuffer key)
        {
            super(client, cf, key);
        }

        public void tryPerformAction(ConsistencyLevel cl) throws Exception
        {
            assertColumnEqual(name, value, timestamp, getColumn(client, key, cf, name, cl));
        }
    }

    protected class Insert extends RetryingAction
    {
        public Insert(Cassandra.Client client, String cf, ByteBuffer key)
        {
            super(client, cf, key);
        }

        public void tryPerformAction(ConsistencyLevel cl) throws Exception
        {
            insert(client, key, cf, name, value, timestamp, cl);
        }
    }

    /** Performs an action repeatedly until timeout, success or failure. */
    protected abstract class RetryingAction
    {
        protected Cassandra.Client client;
        protected String cf;
        protected ByteBuffer key;
        protected String name;
        protected String value;
        protected long timestamp;

        private Set<Class<Exception>> expected = new HashSet<Class<Exception>>();
        private long timeout = StorageService.RING_DELAY;

        public RetryingAction(Cassandra.Client client, String cf, ByteBuffer key)
        {
            this.client = client;
            this.cf = cf;
            this.key = key;
            this.timestamp = 0;
        }

        public RetryingAction name(String name)
        {
            this.name = name; return this;
        }

        /** The value to expect for the return column, or null to expect the column to be missing. */
        public RetryingAction value(String value)
        {
            this.value = value; return this;
        }
       
        /** The total time to allow before failing. */
        public RetryingAction timeout(long timeout)
        {
            this.timeout = timeout; return this;
        }

        /** The expected timestamp of the returned column. */
        public RetryingAction timestamp(long timestamp)
        {
            this.timestamp = timestamp; return this;
        }

        /** The exception classes that indicate success. */
        public RetryingAction expecting(Class... tempExceptions)
        {
            this.expected.clear();
            for (Class exclass : tempExceptions)
                expected.add((Class<Exception>)exclass);
            return this;
        }

        public void perform(ConsistencyLevel cl) throws AssertionError
        {
            long deadline = System.currentTimeMillis() + timeout;
            int attempts = 0;
            String template = "%s for " + this + " after %d attempt(s) with %d ms to spare.";
            Exception e = null;
            while(deadline > System.currentTimeMillis())
            {
                try
                {
                    attempts++;
                    tryPerformAction(cl);
                    logger.info(String.format(template, "Succeeded", attempts, deadline - System.currentTimeMillis()));
                    return;
                }
                catch (Exception ex)
                {
                    e = ex;
                    if (!expected.contains(ex.getClass()))
                        continue;
                    logger.info(String.format(template, "Caught expected exception: " + e, attempts, deadline - System.currentTimeMillis()));
                    return;
                }
            }
            String err = String.format(template, "Caught unexpected: " + e, attempts, deadline - System.currentTimeMillis());
            logger.error(err);
            throw new AssertionError(err);
        }
       
        public String toString()
        {
            return this.getClass() + "(" + key + "," + name + ")";
        }

        protected abstract void tryPerformAction(ConsistencyLevel cl) throws Exception;
    }

    protected List<ColumnOrSuperColumn> get_slice(Cassandra.Client client, ByteBuffer key, String cf, ConsistencyLevel cl)
      throws InvalidRequestException, UnavailableException, TimedOutException, TException
    {
        SlicePredicate sp = new SlicePredicate();
        sp.setSlice_range(
            new SliceRange(
                ByteBuffer.wrap(new byte[0]),
                ByteBuffer.wrap(new byte[0]),
                false,
                1000
                )
            );
        return client.get_slice(key, new ColumnParent(cf), sp, cl);
    }

    protected void assertColumnEqual(String name, String value, long timestamp, Column col)
    {
        assertEquals(ByteBufferUtil.bytes(name), col.name);
        assertEquals(ByteBufferUtil.bytes(value), col.value);
        assertEquals(timestamp, col.timestamp);
    }

    protected List<InetAddress> endpointsForKey(InetAddress seed, ByteBuffer key, String keyspace)
        throws IOException
    {
        RingCache ring = new RingCache(keyspace, new RandomPartitioner(), seed.getHostAddress(), 9160);
        List<InetAddress> privateendpoints = ring.getEndpoint(key);
        List<InetAddress> endpoints = new ArrayList<InetAddress>();
        for (InetAddress endpoint : privateendpoints)
        {
            endpoints.add(controller.getPublicHost(endpoint));
        }
        return endpoints;
    }

    protected InetAddress nonEndpointForKey(InetAddress seed, ByteBuffer key, String keyspace)
        throws IOException
    {
        List<InetAddress> endpoints = endpointsForKey(seed, key, keyspace);
        for (InetAddress host : controller.getHosts())
        {
            if (!endpoints.contains(host))
            {
                return host;
            }
        }
        return null;
    }

    protected ByteBuffer newKey()
    {
        return ByteBufferUtil.bytes(String.format("test.key.%d", System.currentTimeMillis()));
    }
}
TOP

Related Classes of org.apache.cassandra.MutationTest$Insert

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.