Commit 41ba9d16 authored by chiaming2000's avatar chiaming2000
Browse files

Check max key range size and max version length to not exceed max

allowed sizes (1024 and 2048).

A client request would fail (with error code set to INVALID_REQUEST) if
an operation can not pass the validation.
parent 0cb7fed1
Loading
Loading
Loading
Loading
+24 −12
Original line number Diff line number Diff line
@@ -65,6 +65,9 @@ public class KVOp {
    //max key size
    private static int maxKeySize = SimulatorConfiguration.getMaxSupportedKeySize();
    
   //max version size
    private static int maxVersionSize = SimulatorConfiguration.getMaxSupportedVersionSize();
    
    //max key range size
    //private static final int MAX_KEY_RANGE_SIZE = 1024;
    
@@ -162,6 +165,10 @@ public class KVOp {
                      //check max key length
                       checkMaxKeyLenth (key.size());
                       
                       //check max version size
                       ByteString bs = requestKeyValue.getNewVersion();
                       checkMaxVersionLength (bs);

                        if (isSupportedValueSize(kmreq) == false) {
                            throw new KvException(StatusCode.INVALID_REQUEST,
                                    "value size exceeded max supported size. Supported size: "
@@ -211,6 +218,10 @@ public class KVOp {
                        //check max key length
                        checkMaxKeyLenth (key.size());
                        
                        //check max version size
                        ByteString bs = requestKeyValue.getDbVersion();
                        checkMaxVersionLength (bs);
                        
                        Authorizer.checkPermission(aclmap, request.getCommand()
                                .getHeader().getIdentity(), Permission.DELETE,
                                key);
@@ -402,20 +413,21 @@ public class KVOp {
    
    private static void checkMaxKeyLenth (int len) throws InvalidRequestException {
        if (len > maxKeySize) {
            throw new InvalidRequestException ("key length exceeds max size, size=" + maxKeySize);
            throw new InvalidRequestException ("key length exceeds max size, size=" + maxKeySize + ", request size=" + len);
        }
    }
    
    private static void checkMaxVersionLength (ByteString bs) throws InvalidRequestException {
   
        int len = 0;
        if (bs != null) {
            len = bs.size();
        }
        
        if ( len > maxVersionSize) {
            throw new InvalidRequestException ("max version exceeds max allowed size " + maxVersionSize + ", request version size=" + len);
        }
    }
    
//    private static void checkMaxKeyRange (int len) throws InvalidRequestException {
//        if (len > MAX_KEY_RANGE_SIZE) {
//            throw new InvalidRequestException ("max key range exceeds " + MAX_KEY_RANGE_SIZE);
//        }
//    }
//    
//    private static void checkMaxVersion (int len) throws InvalidRequestException {
//        if (len > MAX_VERSION_SIZE) {
//            throw new InvalidRequestException ("max version exceeds " + MAX_VERSION_SIZE);
//        }
//    }

}
+21 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import java.util.Map;
import java.util.SortedMap;
import java.util.logging.Logger;

import kinetic.simulator.SimulatorConfiguration;

import com.google.common.collect.Lists;
import com.google.protobuf.ByteString;
import com.seagate.kinetic.common.lib.Hmac;
@@ -37,6 +39,7 @@ import com.seagate.kinetic.proto.Kinetic.Message.MessageType;
import com.seagate.kinetic.proto.Kinetic.Message.Range;
import com.seagate.kinetic.proto.Kinetic.Message.Status;
import com.seagate.kinetic.simulator.internal.Authorizer;
import com.seagate.kinetic.simulator.internal.InvalidRequestException;
import com.seagate.kinetic.simulator.internal.KVSecurityException;
import com.seagate.kinetic.simulator.lib.MyLogger;

@@ -55,6 +58,9 @@ public class RangeOp {

    private final static Logger LOG = MyLogger.get();
    
    //max key range size.  
    private static int maxRangeSize = SimulatorConfiguration.getMaxSupportedKeyRangeSize();

    static void oops(String s) throws RangeException {
        oops(Status.StatusCode.INTERNAL_ERROR, s);
    }
@@ -76,6 +82,7 @@ public class RangeOp {
        int n;

        try {
             
            try {

                // XXX need to add support for multiple ranges in getKeyRange
@@ -94,6 +101,9 @@ public class RangeOp {
                i2 = r.getEndKeyInclusive();
                n = r.getMaxReturned();
                
                //check max key range size
                checkMaxKeyRange (n);

                reverse = r.getReverse();

                if (n < 1) {
@@ -146,6 +156,9 @@ public class RangeOp {
                .setCode(Status.StatusCode.SUCCESS);

                // TODO check multi-tenant key prefix
            } catch (InvalidRequestException  ire) {
                oops(Status.StatusCode.INVALID_REQUEST,
                        ire.getMessage());
            } catch (Exception e) {
                LOG.fine(e.toString());
                Writer writer = new StringWriter();
@@ -155,6 +168,8 @@ public class RangeOp {
                oops(Status.StatusCode.INTERNAL_ERROR,
                        "Opps2: " + e.getMessage() + "--" + e.toString());
            }
       
            
        } catch (RangeException e) {
            respond.getCommandBuilder().getStatusBuilder().setCode(e.status);
            respond.getCommandBuilder().getStatusBuilder()
@@ -203,4 +218,10 @@ public class RangeOp {
        return rangeAllowedKeys;
    }
    
  private static void checkMaxKeyRange (int len) throws InvalidRequestException {
  if (len > maxRangeSize) {
      throw new InvalidRequestException ("request key range exceeds allowed size " + maxRangeSize + ", request size = " + len);
  }
}

}
+52 −2
Original line number Diff line number Diff line
@@ -148,6 +148,16 @@ public class SimulatorConfiguration extends Properties {
	 */
    private static int maxSupportedKeySize = 4096;
    
    /**
     * max supported version size in bytes
     */
    private static int maxSupportedVersionSize = 2048;
    
    /**
     * max key range size.
     */
    private static int maxSupportedKeyRangeSize = 1024;

	private HeartbeatProvider heartbeatProvider = null;

	/**
@@ -569,7 +579,7 @@ public class SimulatorConfiguration extends Properties {
	/**
     * Get max supported key size in bytes. Default is set to 4096 bytes.
     * 
     * @return max supported value size for the simulator.
     * @return max supported key size for the simulator.
     */
    public static int getMaxSupportedKeySize() {
        return maxSupportedKeySize;
@@ -580,12 +590,52 @@ public class SimulatorConfiguration extends Properties {
     * 
     * @param size
     *            set max supported key size.
     * @see #getMaxSupportedValueSize()
     * @see #getMaxSupportedKeySize()
     */
    public static void setMaxSupportedKeySize(int size) {
        maxSupportedKeySize = size;
    }
    
    /**
     * Get max supported version size in bytes. Default is set to 2048 bytes.
     * 
     * @return max supported key size for the simulator.
     */
    public static int getMaxSupportedVersionSize() {
        return maxSupportedVersionSize;
    }

    /**
     * Set max supported version size, in bytes.
     * 
     * @param size
     *            set max supported version size.
     * @see #getMaxSupportedVersionSize()
     */
    public static void setMaxSupportedVersionSize(int size) {
        maxSupportedVersionSize = size;
    }
    
    /**
     * Get max supported key range size. Default is set to 1024.
     *
     * @return max supported key range size for the simulator.
     */
    public static int getMaxSupportedKeyRangeSize() {
        return maxSupportedKeyRangeSize;
    }

    /**
     * Set max supported key range size, in bytes.
     *
     * @param size
     *            set max supported key range size.
     */
    public static void setMaxSupportedKeyRangeSize(int size) {
        maxSupportedKeyRangeSize = size;
    }


	/**
	 * Set the heartbeat provider for the simulator.
	 * 
+108 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import kinetic.client.KineticClient;
import kinetic.client.KineticClientFactory;
import kinetic.client.KineticException;
import kinetic.client.advanced.AdvancedKineticClient;
import kinetic.simulator.SimulatorConfiguration;

import org.junit.Test;
import org.junit.runner.RunWith;
@@ -2368,4 +2369,111 @@ public class KineticBoundaryTest extends IntegrationTestCase {

        return domains;
    }
    
    /**
     * Test max key range request size cannot exceed max supported size (1024).
     */
    @Test
    public void testGetRangeExceedMaxSize() {
        
        byte[] key0 = toByteArray("key00000000000");
        byte[] key1 = toByteArray("key00000000001");
        
        try {
            int max = SimulatorConfiguration.getMaxSupportedKeyRangeSize();
            getClient().getKeyRange(key0, true, key1, true,  (max +1));
            fail("did not receive expected exception: request key range exceeds max allowed size " + max);
        } catch (KineticException e) {
            logger.info("caught expected exception: " + e.getMessage());
        }

        logger.info(this.testEndInfo());
    }
    
    /**
     * Test max key request size cannot exceed max supported size (4096).
     */
    @Test
    public void testMaxKeyLength() {
        
        int size = SimulatorConfiguration.getMaxSupportedKeySize();
        byte[] key0 = new byte[size];
        try {
            getClient().get(key0);    
        } catch (KineticException e) {
            fail("received unexpected exception: " + e);
        }
        
        byte[] key1 = new byte[size+1];
        
        try {
            getClient().get(key1);
            fail("did not receive expected exception: request key exceeds max allowed size " + size);
        } catch (KineticException e) {
            logger.info("caught expected exception: " + e.getMessage());
        }

        logger.info(this.testEndInfo());
    }
    
    /**
     * Test max version length cannot exceed max supported size (2048).
     */
    @Test
    public void testMaxVersionLength() {
        
        byte[] key = toByteArray("key00000000000");
        byte[] value = toByteArray("value00000000000");
        
        int vlen = SimulatorConfiguration.getMaxSupportedVersionSize();
        
        byte[] version = new byte[vlen];
        Entry entry = new Entry();
        entry.setKey(key);
        entry.setValue(value);
        entry.getEntryMetadata().setVersion(version);
        
        // expect to succeed - allowed version size
        try {
            getClient().putForced(entry);
        } catch (KineticException e) {
            fail("received unexpected exception: " + e);
        }
        
        //expect to fail: exceed max version size to put
        try {
            byte[] version2 = new byte[vlen + 1];
            entry.getEntryMetadata().setVersion(version2);
            
            getClient().putForced(entry);
            fail("did not receive expected exception: request key exceeds max allowed size " + vlen);
        } catch (KineticException e) {
            logger.info("caught expected exception: " + e.getMessage());
        }
        
        //expect fail to delete: exceed max version size
        try {
            byte[] version2 = new byte[vlen + 1];
            entry.getEntryMetadata().setVersion(version2);
           
            getClient().delete(entry);
            fail("did not receive expected exception: request key exceeds max allowed size " + vlen);
        } catch (KineticException e) {
            logger.info("caught expected exception: " + e.getMessage());
        }
        
        //expect succeed to delete.
        try {
            
            entry.getEntryMetadata().setVersion(version);
            //expect succeed
            boolean deleted = getClient().delete(entry);
            
            assertTrue (deleted);
        } catch (KineticException e) {
            fail("received unexpected exception: " + e);
        }
        
        logger.info(this.testEndInfo());
    }
}