HDFS-11853. Ozone: KSM: Add getKey. Contributed by Chen Liang.
This commit is contained in:
parent
59d273b175
commit
72b228a9e6
@ -117,7 +117,20 @@ KsmBucketInfo getBucketInfo(String volumeName, String bucketName)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a block to a container, the block is returned to the client.
|
* Allocate a block to a container, the block is returned to the client.
|
||||||
|
*
|
||||||
|
* @param args the args of the key.
|
||||||
|
* @return KsmKeyInfo isntacne that client uses to talk to container.
|
||||||
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException;
|
KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up for the container of an existing key.
|
||||||
|
*
|
||||||
|
* @param args the args of the key.
|
||||||
|
* @return KsmKeyInfo isntacne that client uses to talk to container.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
KsmKeyInfo lookupKey(KsmKeyArgs args) throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,9 @@
|
|||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
.KeySpaceManagerProtocolProtos.CreateVolumeResponse;
|
.KeySpaceManagerProtocolProtos.CreateVolumeResponse;
|
||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
.KeySpaceManagerProtocolProtos.CreateKeyRequest;
|
.KeySpaceManagerProtocolProtos.LocateKeyRequest;
|
||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
.KeySpaceManagerProtocolProtos.CreateKeyResponse;
|
.KeySpaceManagerProtocolProtos.LocateKeyResponse;
|
||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
.KeySpaceManagerProtocolProtos.KeyArgs;
|
.KeySpaceManagerProtocolProtos.KeyArgs;
|
||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
@ -330,7 +330,7 @@ public KsmBucketInfo getBucketInfo(String volume, String bucket)
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException {
|
public KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException {
|
||||||
CreateKeyRequest.Builder req = CreateKeyRequest.newBuilder();
|
LocateKeyRequest.Builder req = LocateKeyRequest.newBuilder();
|
||||||
KeyArgs keyArgs = KeyArgs.newBuilder()
|
KeyArgs keyArgs = KeyArgs.newBuilder()
|
||||||
.setVolumeName(args.getVolumeName())
|
.setVolumeName(args.getVolumeName())
|
||||||
.setBucketName(args.getBucketName())
|
.setBucketName(args.getBucketName())
|
||||||
@ -338,14 +338,37 @@ public KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException {
|
|||||||
.setDataSize(args.getDataSize()).build();
|
.setDataSize(args.getDataSize()).build();
|
||||||
req.setKeyArgs(keyArgs);
|
req.setKeyArgs(keyArgs);
|
||||||
|
|
||||||
final CreateKeyResponse resp;
|
final LocateKeyResponse resp;
|
||||||
try {
|
try {
|
||||||
resp = rpcProxy.createKey(NULL_RPC_CONTROLLER, req.build());
|
resp = rpcProxy.createKey(NULL_RPC_CONTROLLER, req.build());
|
||||||
} catch (ServiceException e) {
|
} catch (ServiceException e) {
|
||||||
throw ProtobufHelper.getRemoteException(e);
|
throw ProtobufHelper.getRemoteException(e);
|
||||||
}
|
}
|
||||||
if (resp.getStatus() != Status.OK) {
|
if (resp.getStatus() != Status.OK) {
|
||||||
throw new IOException("Get key block failed, error:" +
|
throw new IOException("Get key failed, error:" +
|
||||||
|
resp.getStatus());
|
||||||
|
}
|
||||||
|
return KsmKeyInfo.getFromProtobuf(resp.getKeyInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KsmKeyInfo lookupKey(KsmKeyArgs args) throws IOException {
|
||||||
|
LocateKeyRequest.Builder req = LocateKeyRequest.newBuilder();
|
||||||
|
KeyArgs keyArgs = KeyArgs.newBuilder()
|
||||||
|
.setVolumeName(args.getVolumeName())
|
||||||
|
.setBucketName(args.getBucketName())
|
||||||
|
.setKeyName(args.getKeyName())
|
||||||
|
.setDataSize(args.getDataSize()).build();
|
||||||
|
req.setKeyArgs(keyArgs);
|
||||||
|
|
||||||
|
final LocateKeyResponse resp;
|
||||||
|
try {
|
||||||
|
resp = rpcProxy.lookupKey(NULL_RPC_CONTROLLER, req.build());
|
||||||
|
} catch (ServiceException e) {
|
||||||
|
throw ProtobufHelper.getRemoteException(e);
|
||||||
|
}
|
||||||
|
if (resp.getStatus() != Status.OK) {
|
||||||
|
throw new IOException("Lookup key failed, error:" +
|
||||||
resp.getStatus());
|
resp.getStatus());
|
||||||
}
|
}
|
||||||
return KsmKeyInfo.getFromProtobuf(resp.getKeyInfo());
|
return KsmKeyInfo.getFromProtobuf(resp.getKeyInfo());
|
||||||
|
@ -48,8 +48,10 @@ enum Status {
|
|||||||
BUCKET_NOT_FOUND = 8;
|
BUCKET_NOT_FOUND = 8;
|
||||||
BUCKET_NOT_EMPTY = 9;
|
BUCKET_NOT_EMPTY = 9;
|
||||||
BUCKET_ALREADY_EXISTS = 10;
|
BUCKET_ALREADY_EXISTS = 10;
|
||||||
ACCESS_DENIED = 11;
|
KEY_ALREADY_EXISTS = 11;
|
||||||
INTERNAL_ERROR = 12;
|
KEY_NOT_FOUND = 12;
|
||||||
|
ACCESS_DENIED = 13;
|
||||||
|
INTERNAL_ERROR = 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -228,11 +230,11 @@ message KeyInfo {
|
|||||||
required bool shouldCreateContainer = 7;
|
required bool shouldCreateContainer = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateKeyRequest {
|
message LocateKeyRequest {
|
||||||
required KeyArgs keyArgs = 1;
|
required KeyArgs keyArgs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateKeyResponse {
|
message LocateKeyResponse {
|
||||||
required Status status = 1;
|
required Status status = 1;
|
||||||
optional KeyInfo keyInfo = 2;
|
optional KeyInfo keyInfo = 2;
|
||||||
}
|
}
|
||||||
@ -290,8 +292,14 @@ service KeySpaceManagerService {
|
|||||||
returns(InfoBucketResponse);
|
returns(InfoBucketResponse);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get key block.
|
Get key.
|
||||||
*/
|
*/
|
||||||
rpc createKey(CreateKeyRequest)
|
rpc createKey(LocateKeyRequest)
|
||||||
returns(CreateKeyResponse);
|
returns(LocateKeyResponse);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Look up for an existing key.
|
||||||
|
*/
|
||||||
|
rpc lookupKey(LocateKeyRequest)
|
||||||
|
returns(LocateKeyResponse);
|
||||||
}
|
}
|
@ -33,7 +33,8 @@ public class KSMMetrics {
|
|||||||
private @Metric MutableCounterLong numVolumeInfos;
|
private @Metric MutableCounterLong numVolumeInfos;
|
||||||
private @Metric MutableCounterLong numBucketCreates;
|
private @Metric MutableCounterLong numBucketCreates;
|
||||||
private @Metric MutableCounterLong numBucketInfos;
|
private @Metric MutableCounterLong numBucketInfos;
|
||||||
private @Metric MutableCounterLong numKeyBlockAllocate;
|
private @Metric MutableCounterLong numKeyAllocate;
|
||||||
|
private @Metric MutableCounterLong numKeyLookup;
|
||||||
|
|
||||||
// Failure Metrics
|
// Failure Metrics
|
||||||
private @Metric MutableCounterLong numVolumeCreateFails;
|
private @Metric MutableCounterLong numVolumeCreateFails;
|
||||||
@ -41,7 +42,8 @@ public class KSMMetrics {
|
|||||||
private @Metric MutableCounterLong numVolumeInfoFails;
|
private @Metric MutableCounterLong numVolumeInfoFails;
|
||||||
private @Metric MutableCounterLong numBucketCreateFails;
|
private @Metric MutableCounterLong numBucketCreateFails;
|
||||||
private @Metric MutableCounterLong numBucketInfoFails;
|
private @Metric MutableCounterLong numBucketInfoFails;
|
||||||
private @Metric MutableCounterLong numKeyBlockAllocateFails;
|
private @Metric MutableCounterLong numKeyAllocateFails;
|
||||||
|
private @Metric MutableCounterLong numKeyLookupFails;
|
||||||
|
|
||||||
public KSMMetrics() {
|
public KSMMetrics() {
|
||||||
}
|
}
|
||||||
@ -93,12 +95,20 @@ public void incNumBucketInfoFails() {
|
|||||||
numBucketInfoFails.incr();
|
numBucketInfoFails.incr();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incNumKeyBlockAllocates() {
|
public void incNumKeyAllocates() {
|
||||||
numKeyBlockAllocate.incr();
|
numKeyAllocate.incr();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incNumKeyBlockAllocateFails() {
|
public void incNumKeyAllocateFails() {
|
||||||
numKeyBlockAllocateFails.incr();
|
numKeyAllocateFails.incr();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incNumKeyLookups() {
|
||||||
|
numKeyLookup.incr();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incNumKeyLookupFails() {
|
||||||
|
numKeyLookupFails.incr();
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@ -152,12 +162,22 @@ public long getNumBucketInfoFails() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public long getNumKeyBlockAllocates() {
|
public long getNumKeyAllocates() {
|
||||||
return numKeyBlockAllocate.value();
|
return numKeyAllocate.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public long getNumKeyBlockAllocateFailes() {
|
public long getNumKeyAllocateFails() {
|
||||||
return numKeyBlockAllocateFails.value();
|
return numKeyAllocateFails.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public long getNumKeyLookups() {
|
||||||
|
return numKeyLookup.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public long getNumKeyLookupFails() {
|
||||||
|
return numKeyLookupFails.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,4 +42,14 @@ public interface KeyManager {
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException;
|
KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up an existing key. Return the info of the key to client side, which
|
||||||
|
* DistributedStorageHandler will use to access the data on datanode.
|
||||||
|
*
|
||||||
|
* @param args the args of the key provided by client.
|
||||||
|
* @return a KsmKeyInfo instance client uses to talk to container.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
KsmKeyInfo lookupKey(KsmKeyArgs args) throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
import org.apache.hadoop.ksm.helpers.KsmKeyArgs;
|
import org.apache.hadoop.ksm.helpers.KsmKeyArgs;
|
||||||
import org.apache.hadoop.ksm.helpers.KsmKeyInfo;
|
import org.apache.hadoop.ksm.helpers.KsmKeyInfo;
|
||||||
import org.apache.hadoop.ozone.ksm.exceptions.KSMException;
|
import org.apache.hadoop.ozone.ksm.exceptions.KSMException;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.KeySpaceManagerProtocolProtos.KeyInfo;
|
||||||
import org.apache.hadoop.scm.container.common.helpers.AllocatedBlock;
|
import org.apache.hadoop.scm.container.common.helpers.AllocatedBlock;
|
||||||
import org.apache.hadoop.scm.protocol.ScmBlockLocationProtocol;
|
import org.apache.hadoop.scm.protocol.ScmBlockLocationProtocol;
|
||||||
import org.iq80.leveldb.DBException;
|
import org.iq80.leveldb.DBException;
|
||||||
@ -106,4 +107,31 @@ public KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException {
|
|||||||
metadataManager.writeLock().unlock();
|
metadataManager.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KsmKeyInfo lookupKey(KsmKeyArgs args) throws IOException {
|
||||||
|
Preconditions.checkNotNull(args);
|
||||||
|
metadataManager.writeLock().lock();
|
||||||
|
String volumeName = args.getVolumeName();
|
||||||
|
String bucketName = args.getBucketName();
|
||||||
|
String keyName = args.getKeyName();
|
||||||
|
try {
|
||||||
|
byte[] keyKey = metadataManager.getDBKeyForKey(
|
||||||
|
volumeName, bucketName, keyName);
|
||||||
|
byte[] value = metadataManager.get(keyKey);
|
||||||
|
if (value == null) {
|
||||||
|
LOG.error("Key: {} not found", keyKey);
|
||||||
|
throw new KSMException("Key not found",
|
||||||
|
KSMException.ResultCodes.FAILED_KEY_NOT_FOUND);
|
||||||
|
}
|
||||||
|
return KsmKeyInfo.getFromProtobuf(KeyInfo.parseFrom(value));
|
||||||
|
} catch (DBException ex) {
|
||||||
|
LOG.error("Get key failed for volume:{} bucket:{} key:{}",
|
||||||
|
volumeName, bucketName, keyName, ex);
|
||||||
|
throw new KSMException(ex.getMessage(),
|
||||||
|
KSMException.ResultCodes.FAILED_KEY_NOT_FOUND);
|
||||||
|
} finally {
|
||||||
|
metadataManager.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -408,18 +408,37 @@ public KsmBucketInfo getBucketInfo(String volume, String bucket)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a key block.
|
* Allocate a key.
|
||||||
|
*
|
||||||
* @param args - attributes of the key.
|
* @param args - attributes of the key.
|
||||||
* @return
|
* @return KsmKeyInfo - the info about the allocated key.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException {
|
public KsmKeyInfo allocateKey(KsmKeyArgs args) throws IOException {
|
||||||
try {
|
try {
|
||||||
metrics.incNumKeyBlockAllocates();
|
metrics.incNumKeyAllocates();
|
||||||
return keyManager.allocateKey(args);
|
return keyManager.allocateKey(args);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
metrics.incNumKeyBlockAllocateFails();
|
metrics.incNumKeyAllocateFails();
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup a key.
|
||||||
|
*
|
||||||
|
* @param args - attributes of the key.
|
||||||
|
* @return KsmKeyInfo - the info about the requested key.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public KsmKeyInfo lookupKey(KsmKeyArgs args) throws IOException {
|
||||||
|
try {
|
||||||
|
metrics.incNumKeyLookups();
|
||||||
|
return keyManager.lookupKey(args);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
metrics.incNumKeyLookupFails();
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,7 @@ public enum ResultCodes {
|
|||||||
FAILED_BUCKET_ALREADY_EXISTS,
|
FAILED_BUCKET_ALREADY_EXISTS,
|
||||||
FAILED_BUCKET_NOT_FOUND,
|
FAILED_BUCKET_NOT_FOUND,
|
||||||
FAILED_KEY_ALREADY_EXISTS,
|
FAILED_KEY_ALREADY_EXISTS,
|
||||||
|
FAILED_KEY_NOT_FOUND,
|
||||||
FAILED_INTERNAL_ERROR
|
FAILED_INTERNAL_ERROR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,9 @@
|
|||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
.KeySpaceManagerProtocolProtos.CreateVolumeResponse;
|
.KeySpaceManagerProtocolProtos.CreateVolumeResponse;
|
||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
.KeySpaceManagerProtocolProtos.CreateKeyRequest;
|
.KeySpaceManagerProtocolProtos.LocateKeyRequest;
|
||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
.KeySpaceManagerProtocolProtos.CreateKeyResponse;
|
.KeySpaceManagerProtocolProtos.LocateKeyResponse;
|
||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
.KeySpaceManagerProtocolProtos.KeyArgs;
|
.KeySpaceManagerProtocolProtos.KeyArgs;
|
||||||
import org.apache.hadoop.ozone.protocol.proto
|
import org.apache.hadoop.ozone.protocol.proto
|
||||||
@ -105,6 +105,10 @@ private Status exceptionToResponseStatus(IOException ex) {
|
|||||||
return Status.BUCKET_ALREADY_EXISTS;
|
return Status.BUCKET_ALREADY_EXISTS;
|
||||||
case FAILED_BUCKET_NOT_FOUND:
|
case FAILED_BUCKET_NOT_FOUND:
|
||||||
return Status.BUCKET_NOT_FOUND;
|
return Status.BUCKET_NOT_FOUND;
|
||||||
|
case FAILED_KEY_ALREADY_EXISTS:
|
||||||
|
return Status.KEY_ALREADY_EXISTS;
|
||||||
|
case FAILED_KEY_NOT_FOUND:
|
||||||
|
return Status.KEY_NOT_FOUND;
|
||||||
default:
|
default:
|
||||||
return Status.INTERNAL_ERROR;
|
return Status.INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
@ -221,11 +225,11 @@ public InfoBucketResponse infoBucket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CreateKeyResponse createKey(
|
public LocateKeyResponse createKey(
|
||||||
RpcController controller, CreateKeyRequest request
|
RpcController controller, LocateKeyRequest request
|
||||||
) throws ServiceException {
|
) throws ServiceException {
|
||||||
CreateKeyResponse.Builder resp =
|
LocateKeyResponse.Builder resp =
|
||||||
CreateKeyResponse.newBuilder();
|
LocateKeyResponse.newBuilder();
|
||||||
try {
|
try {
|
||||||
KeyArgs keyArgs = request.getKeyArgs();
|
KeyArgs keyArgs = request.getKeyArgs();
|
||||||
KsmKeyArgs ksmKeyArgs = new KsmKeyArgs.Builder()
|
KsmKeyArgs ksmKeyArgs = new KsmKeyArgs.Builder()
|
||||||
@ -242,4 +246,27 @@ public CreateKeyResponse createKey(
|
|||||||
}
|
}
|
||||||
return resp.build();
|
return resp.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocateKeyResponse lookupKey(
|
||||||
|
RpcController controller, LocateKeyRequest request
|
||||||
|
) throws ServiceException {
|
||||||
|
LocateKeyResponse.Builder resp =
|
||||||
|
LocateKeyResponse.newBuilder();
|
||||||
|
try {
|
||||||
|
KeyArgs keyArgs = request.getKeyArgs();
|
||||||
|
KsmKeyArgs ksmKeyArgs = new KsmKeyArgs.Builder()
|
||||||
|
.setVolumeName(keyArgs.getVolumeName())
|
||||||
|
.setBucketName(keyArgs.getBucketName())
|
||||||
|
.setKeyName(keyArgs.getKeyName())
|
||||||
|
.setDataSize(keyArgs.getDataSize())
|
||||||
|
.build();
|
||||||
|
KsmKeyInfo keyInfo = impl.lookupKey(ksmKeyArgs);
|
||||||
|
resp.setKeyInfo(keyInfo.getProtobuf());
|
||||||
|
resp.setStatus(Status.OK);
|
||||||
|
} catch (IOException e) {
|
||||||
|
resp.setStatus(exceptionToResponseStatus(e));
|
||||||
|
}
|
||||||
|
return resp.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,11 +316,21 @@ public void commitKey(KeyArgs args, OutputStream stream) throws
|
|||||||
@Override
|
@Override
|
||||||
public LengthInputStream newKeyReader(KeyArgs args) throws IOException,
|
public LengthInputStream newKeyReader(KeyArgs args) throws IOException,
|
||||||
OzoneException {
|
OzoneException {
|
||||||
|
KsmKeyArgs keyArgs = new KsmKeyArgs.Builder()
|
||||||
|
.setVolumeName(args.getVolumeName())
|
||||||
|
.setBucketName(args.getBucketName())
|
||||||
|
.setKeyName(args.getKeyName())
|
||||||
|
.setDataSize(args.getSize())
|
||||||
|
.build();
|
||||||
|
KsmKeyInfo keyInfo = keySpaceManagerClient.lookupKey(keyArgs);
|
||||||
String containerKey = buildContainerKey(args.getVolumeName(),
|
String containerKey = buildContainerKey(args.getVolumeName(),
|
||||||
args.getBucketName(), args.getKeyName());
|
args.getBucketName(), args.getKeyName());
|
||||||
XceiverClientSpi xceiverClient = acquireXceiverClient(containerKey);
|
String containerName = keyInfo.getContainerName();
|
||||||
|
XceiverClientSpi xceiverClient = getContainer(containerName);
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
|
LOG.debug("get key accessing {} {}",
|
||||||
|
xceiverClient.getPipeline().getContainerName(), containerKey);
|
||||||
KeyData containerKeyData = containerKeyDataForRead(
|
KeyData containerKeyData = containerKeyDataForRead(
|
||||||
xceiverClient.getPipeline().getContainerName(), containerKey);
|
xceiverClient.getPipeline().getContainerName(), containerKey);
|
||||||
GetKeyResponseProto response = getKey(xceiverClient, containerKeyData,
|
GetKeyResponseProto response = getKey(xceiverClient, containerKeyData,
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
import org.apache.commons.lang.RandomStringUtils;
|
import org.apache.commons.lang.RandomStringUtils;
|
||||||
import org.apache.hadoop.fs.StorageType;
|
import org.apache.hadoop.fs.StorageType;
|
||||||
|
import org.apache.hadoop.hdfs.DFSUtil;
|
||||||
import org.apache.hadoop.hdfs.server.datanode.ObjectStoreHandler;
|
import org.apache.hadoop.hdfs.server.datanode.ObjectStoreHandler;
|
||||||
import org.apache.hadoop.ozone.MiniOzoneCluster;
|
import org.apache.hadoop.ozone.MiniOzoneCluster;
|
||||||
import org.apache.hadoop.ozone.OzoneConfigKeys;
|
import org.apache.hadoop.ozone.OzoneConfigKeys;
|
||||||
@ -37,10 +38,13 @@
|
|||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@ -54,6 +58,9 @@ public class TestKeySpaceManager {
|
|||||||
private static UserArgs userArgs;
|
private static UserArgs userArgs;
|
||||||
private static KSMMetrics ksmMetrics;
|
private static KSMMetrics ksmMetrics;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException exception = ExpectedException.none();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a MiniDFSCluster for testing.
|
* Create a MiniDFSCluster for testing.
|
||||||
* <p>
|
* <p>
|
||||||
@ -197,14 +204,22 @@ public void testCreateBucket() throws IOException, OzoneException {
|
|||||||
Assert.assertEquals(0, ksmMetrics.getNumBucketInfoFails());
|
Assert.assertEquals(0, ksmMetrics.getNumBucketInfoFails());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic test of both putKey and getKey from KSM, as one can not be tested
|
||||||
|
* without the other.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetKeyWriter() throws IOException, OzoneException {
|
public void testGetKeyWriterReader() throws IOException, OzoneException {
|
||||||
String userName = "user" + RandomStringUtils.randomNumeric(5);
|
String userName = "user" + RandomStringUtils.randomNumeric(5);
|
||||||
String adminName = "admin" + RandomStringUtils.randomNumeric(5);
|
String adminName = "admin" + RandomStringUtils.randomNumeric(5);
|
||||||
String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
|
String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
|
||||||
String bucketName = "bucket" + RandomStringUtils.randomNumeric(5);
|
String bucketName = "bucket" + RandomStringUtils.randomNumeric(5);
|
||||||
String keyName = "key" + RandomStringUtils.randomNumeric(5);
|
String keyName = "key" + RandomStringUtils.randomNumeric(5);
|
||||||
Assert.assertEquals(0, ksmMetrics.getNumKeyBlockAllocates());
|
long numKeyAllocates = ksmMetrics.getNumKeyAllocates();
|
||||||
|
long numKeyLookups = ksmMetrics.getNumKeyLookups();
|
||||||
|
|
||||||
VolumeArgs createVolumeArgs = new VolumeArgs(volumeName, userArgs);
|
VolumeArgs createVolumeArgs = new VolumeArgs(volumeName, userArgs);
|
||||||
createVolumeArgs.setUserName(userName);
|
createVolumeArgs.setUserName(userName);
|
||||||
@ -219,10 +234,94 @@ public void testGetKeyWriter() throws IOException, OzoneException {
|
|||||||
|
|
||||||
String dataString = RandomStringUtils.randomAscii(100);
|
String dataString = RandomStringUtils.randomAscii(100);
|
||||||
KeyArgs keyArgs = new KeyArgs(volumeName, bucketName, keyName, userArgs);
|
KeyArgs keyArgs = new KeyArgs(volumeName, bucketName, keyName, userArgs);
|
||||||
keyArgs.setSize(4096);
|
keyArgs.setSize(100);
|
||||||
try (OutputStream stream = storageHandler.newKeyWriter(keyArgs)) {
|
try (OutputStream stream = storageHandler.newKeyWriter(keyArgs)) {
|
||||||
stream.write(dataString.getBytes());
|
stream.write(dataString.getBytes());
|
||||||
}
|
}
|
||||||
Assert.assertEquals(1, ksmMetrics.getNumKeyBlockAllocates());
|
Assert.assertEquals(1 + numKeyAllocates, ksmMetrics.getNumKeyAllocates());
|
||||||
|
|
||||||
|
byte[] data = new byte[dataString.length()];
|
||||||
|
try (InputStream in = storageHandler.newKeyReader(keyArgs)) {
|
||||||
|
in.read(data);
|
||||||
|
}
|
||||||
|
Assert.assertEquals(dataString, DFSUtil.bytes2String(data));
|
||||||
|
Assert.assertEquals(1 + numKeyLookups, ksmMetrics.getNumKeyLookups());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test write the same key twice, the second write should fail, as currently
|
||||||
|
* key overwrite is not supported.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testKeyOverwrite() throws IOException, OzoneException {
|
||||||
|
String userName = "user" + RandomStringUtils.randomNumeric(5);
|
||||||
|
String adminName = "admin" + RandomStringUtils.randomNumeric(5);
|
||||||
|
String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
|
||||||
|
String bucketName = "bucket" + RandomStringUtils.randomNumeric(5);
|
||||||
|
String keyName = "key" + RandomStringUtils.randomNumeric(5);
|
||||||
|
long numKeyAllocateFails = ksmMetrics.getNumKeyAllocateFails();
|
||||||
|
|
||||||
|
VolumeArgs createVolumeArgs = new VolumeArgs(volumeName, userArgs);
|
||||||
|
createVolumeArgs.setUserName(userName);
|
||||||
|
createVolumeArgs.setAdminName(adminName);
|
||||||
|
storageHandler.createVolume(createVolumeArgs);
|
||||||
|
|
||||||
|
BucketArgs bucketArgs = new BucketArgs(bucketName, createVolumeArgs);
|
||||||
|
bucketArgs.setAddAcls(new LinkedList<>());
|
||||||
|
bucketArgs.setRemoveAcls(new LinkedList<>());
|
||||||
|
bucketArgs.setStorageType(StorageType.DISK);
|
||||||
|
storageHandler.createBucket(bucketArgs);
|
||||||
|
|
||||||
|
KeyArgs keyArgs = new KeyArgs(volumeName, bucketName, keyName, userArgs);
|
||||||
|
keyArgs.setSize(100);
|
||||||
|
String dataString = RandomStringUtils.randomAscii(100);
|
||||||
|
try (OutputStream stream = storageHandler.newKeyWriter(keyArgs)) {
|
||||||
|
stream.write(dataString.getBytes());
|
||||||
|
}
|
||||||
|
// try to put the same keyArg, should raise KEY_ALREADY_EXISTS exception
|
||||||
|
exception.expect(IOException.class);
|
||||||
|
exception.expectMessage("KEY_ALREADY_EXISTS");
|
||||||
|
KeyArgs keyArgs2 = new KeyArgs(volumeName, bucketName, keyName, userArgs);
|
||||||
|
storageHandler.newKeyWriter(keyArgs2);
|
||||||
|
Assert.assertEquals(1 + numKeyAllocateFails,
|
||||||
|
ksmMetrics.getNumKeyAllocateFails());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test get a non-exiting key.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetNonExistKey() throws IOException, OzoneException {
|
||||||
|
String userName = "user" + RandomStringUtils.randomNumeric(5);
|
||||||
|
String adminName = "admin" + RandomStringUtils.randomNumeric(5);
|
||||||
|
String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
|
||||||
|
String bucketName = "bucket" + RandomStringUtils.randomNumeric(5);
|
||||||
|
String keyName = "key" + RandomStringUtils.randomNumeric(5);
|
||||||
|
long numKeyLookupFails = ksmMetrics.getNumKeyLookupFails();
|
||||||
|
|
||||||
|
VolumeArgs createVolumeArgs = new VolumeArgs(volumeName, userArgs);
|
||||||
|
createVolumeArgs.setUserName(userName);
|
||||||
|
createVolumeArgs.setAdminName(adminName);
|
||||||
|
storageHandler.createVolume(createVolumeArgs);
|
||||||
|
|
||||||
|
BucketArgs bucketArgs = new BucketArgs(bucketName, createVolumeArgs);
|
||||||
|
bucketArgs.setAddAcls(new LinkedList<>());
|
||||||
|
bucketArgs.setRemoveAcls(new LinkedList<>());
|
||||||
|
bucketArgs.setStorageType(StorageType.DISK);
|
||||||
|
storageHandler.createBucket(bucketArgs);
|
||||||
|
|
||||||
|
KeyArgs keyArgs = new KeyArgs(volumeName, bucketName, keyName, userArgs);
|
||||||
|
// try to get the key, should fail as it hasn't been created
|
||||||
|
exception.expect(IOException.class);
|
||||||
|
exception.expectMessage("KEY_NOT_FOUND");
|
||||||
|
storageHandler.newKeyReader(keyArgs);
|
||||||
|
Assert.assertEquals(1 + numKeyLookupFails,
|
||||||
|
ksmMetrics.getNumKeyLookupFails());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user