Add Status to RocksDBException so that meaningful function result Status from the C++ API isn't lost (#1273)
parent
ecf9003860
commit
ffdf6eee19
@ -0,0 +1,78 @@ |
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
#include <jni.h> |
||||
|
||||
#include "include/org_rocksdb_RocksDBExceptionTest.h" |
||||
|
||||
#include "rocksdb/slice.h" |
||||
#include "rocksdb/status.h" |
||||
#include "rocksjni/portal.h" |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDBExceptionTest |
||||
* Method: raiseException |
||||
* Signature: ()V |
||||
*/ |
||||
void Java_org_rocksdb_RocksDBExceptionTest_raiseException(JNIEnv* env, |
||||
jobject jobj) { |
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, std::string("test message")); |
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDBExceptionTest |
||||
* Method: raiseExceptionWithStatusCode |
||||
* Signature: ()V |
||||
*/ |
||||
void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionWithStatusCode( |
||||
JNIEnv* env, jobject jobj) { |
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, "test message", |
||||
rocksdb::Status::NotSupported()); |
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDBExceptionTest |
||||
* Method: raiseExceptionNoMsgWithStatusCode |
||||
* Signature: ()V |
||||
*/ |
||||
void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionNoMsgWithStatusCode( |
||||
JNIEnv* env, jobject jobj) { |
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotSupported()); |
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDBExceptionTest |
||||
* Method: raiseExceptionWithStatusCodeSubCode |
||||
* Signature: ()V |
||||
*/ |
||||
void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionWithStatusCodeSubCode( |
||||
JNIEnv* env, jobject jobj) { |
||||
rocksdb::RocksDBExceptionJni::ThrowNew( |
||||
env, "test message", |
||||
rocksdb::Status::TimedOut(rocksdb::Status::SubCode::kLockTimeout)); |
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDBExceptionTest |
||||
* Method: raiseExceptionNoMsgWithStatusCodeSubCode |
||||
* Signature: ()V |
||||
*/ |
||||
void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionNoMsgWithStatusCodeSubCode( |
||||
JNIEnv* env, jobject jobj) { |
||||
rocksdb::RocksDBExceptionJni::ThrowNew( |
||||
env, rocksdb::Status::TimedOut(rocksdb::Status::SubCode::kLockTimeout)); |
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDBExceptionTest |
||||
* Method: raiseExceptionWithStatusCodeState |
||||
* Signature: ()V |
||||
*/ |
||||
void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionWithStatusCodeState( |
||||
JNIEnv* env, jobject jobj) { |
||||
rocksdb::Slice state("test state"); |
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, "test message", |
||||
rocksdb::Status::NotSupported(state)); |
||||
} |
@ -0,0 +1,113 @@ |
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
package org.rocksdb; |
||||
|
||||
/** |
||||
* Represents the status returned by a function call in RocksDB. |
||||
* |
||||
* Currently only used with {@link RocksDBException} when the |
||||
* status is not {@link Code#Ok} |
||||
*/ |
||||
public class Status { |
||||
private final Code code; |
||||
/* @Nullable */ private final SubCode subCode; |
||||
/* @Nullable */ private final String state; |
||||
|
||||
public Status(final Code code, final SubCode subCode, final String state) { |
||||
this.code = code; |
||||
this.subCode = subCode; |
||||
this.state = state; |
||||
} |
||||
|
||||
/** |
||||
* Intentionally private as this will be called from JNI |
||||
*/ |
||||
private Status(final byte code, final byte subCode, final String state) { |
||||
this.code = Code.getCode(code); |
||||
this.subCode = SubCode.getSubCode(subCode); |
||||
this.state = state; |
||||
} |
||||
|
||||
public Code getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public SubCode getSubCode() { |
||||
return subCode; |
||||
} |
||||
|
||||
public String getState() { |
||||
return state; |
||||
} |
||||
|
||||
public String getCodeString() { |
||||
final StringBuilder builder = new StringBuilder() |
||||
.append(code.name()); |
||||
if(subCode != null && subCode != SubCode.None) { |
||||
builder.append("(") |
||||
.append(subCode.name()) |
||||
.append(")"); |
||||
} |
||||
return builder.toString(); |
||||
} |
||||
|
||||
public enum Code { |
||||
Ok( (byte)0x0), |
||||
NotFound( (byte)0x1), |
||||
Corruption( (byte)0x2), |
||||
NotSupported( (byte)0x3), |
||||
InvalidArgument( (byte)0x4), |
||||
IOError( (byte)0x5), |
||||
MergeInProgress( (byte)0x6), |
||||
Incomplete( (byte)0x7), |
||||
ShutdownInProgress( (byte)0x8), |
||||
TimedOut( (byte)0x9), |
||||
Aborted( (byte)0xA), |
||||
Busy( (byte)0xB), |
||||
Expired( (byte)0xC), |
||||
TryAgain( (byte)0xD); |
||||
|
||||
private final byte value; |
||||
|
||||
Code(final byte value) { |
||||
this.value = value; |
||||
} |
||||
|
||||
public static Code getCode(final byte value) { |
||||
for (final Code code : Code.values()) { |
||||
if (code.value == value){ |
||||
return code; |
||||
} |
||||
} |
||||
throw new IllegalArgumentException( |
||||
"Illegal value provided for Code."); |
||||
} |
||||
} |
||||
|
||||
public enum SubCode { |
||||
None( (byte)0x0), |
||||
MutexTimeout( (byte)0x1), |
||||
LockTimeout( (byte)0x2), |
||||
LockLimit( (byte)0x3), |
||||
MaxSubCode( (byte)0xFE); |
||||
|
||||
private final byte value; |
||||
|
||||
SubCode(final byte value) { |
||||
this.value = value; |
||||
} |
||||
|
||||
public static SubCode getSubCode(final byte value) { |
||||
for (final SubCode subCode : SubCode.values()) { |
||||
if (subCode.value == value){ |
||||
return subCode; |
||||
} |
||||
} |
||||
throw new IllegalArgumentException( |
||||
"Illegal value provided for SubCode."); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,115 @@ |
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
package org.rocksdb; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.rocksdb.Status.Code; |
||||
import org.rocksdb.Status.SubCode; |
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.junit.Assert.fail; |
||||
|
||||
public class RocksDBExceptionTest { |
||||
|
||||
@Test |
||||
public void exception() { |
||||
try { |
||||
raiseException(); |
||||
} catch(final RocksDBException e) { |
||||
assertThat(e.getStatus()).isNull(); |
||||
assertThat(e.getMessage()).isEqualTo("test message"); |
||||
return; |
||||
} |
||||
fail(); |
||||
} |
||||
|
||||
@Test |
||||
public void exceptionWithStatusCode() { |
||||
try { |
||||
raiseExceptionWithStatusCode(); |
||||
} catch(final RocksDBException e) { |
||||
assertThat(e.getStatus()).isNotNull(); |
||||
assertThat(e.getStatus().getCode()).isEqualTo(Code.NotSupported); |
||||
assertThat(e.getStatus().getSubCode()).isEqualTo(SubCode.None); |
||||
assertThat(e.getStatus().getState()).isNull(); |
||||
assertThat(e.getMessage()).isEqualTo("test message"); |
||||
return; |
||||
} |
||||
fail(); |
||||
} |
||||
|
||||
@Test |
||||
public void exceptionNoMsgWithStatusCode() { |
||||
try { |
||||
raiseExceptionNoMsgWithStatusCode(); |
||||
} catch(final RocksDBException e) { |
||||
assertThat(e.getStatus()).isNotNull(); |
||||
assertThat(e.getStatus().getCode()).isEqualTo(Code.NotSupported); |
||||
assertThat(e.getStatus().getSubCode()).isEqualTo(SubCode.None); |
||||
assertThat(e.getStatus().getState()).isNull(); |
||||
assertThat(e.getMessage()).isEqualTo(Code.NotSupported.name()); |
||||
return; |
||||
} |
||||
fail(); |
||||
} |
||||
|
||||
@Test |
||||
public void exceptionWithStatusCodeSubCode() { |
||||
try { |
||||
raiseExceptionWithStatusCodeSubCode(); |
||||
} catch(final RocksDBException e) { |
||||
assertThat(e.getStatus()).isNotNull(); |
||||
assertThat(e.getStatus().getCode()).isEqualTo(Code.TimedOut); |
||||
assertThat(e.getStatus().getSubCode()) |
||||
.isEqualTo(Status.SubCode.LockTimeout); |
||||
assertThat(e.getStatus().getState()).isNull(); |
||||
assertThat(e.getMessage()).isEqualTo("test message"); |
||||
return; |
||||
} |
||||
fail(); |
||||
} |
||||
|
||||
@Test |
||||
public void exceptionNoMsgWithStatusCodeSubCode() { |
||||
try { |
||||
raiseExceptionNoMsgWithStatusCodeSubCode(); |
||||
} catch(final RocksDBException e) { |
||||
assertThat(e.getStatus()).isNotNull(); |
||||
assertThat(e.getStatus().getCode()).isEqualTo(Code.TimedOut); |
||||
assertThat(e.getStatus().getSubCode()).isEqualTo(SubCode.LockTimeout); |
||||
assertThat(e.getStatus().getState()).isNull(); |
||||
assertThat(e.getMessage()).isEqualTo(Code.TimedOut.name() + |
||||
"(" + SubCode.LockTimeout.name() + ")"); |
||||
return; |
||||
} |
||||
fail(); |
||||
} |
||||
|
||||
@Test |
||||
public void exceptionWithStatusCodeState() { |
||||
try { |
||||
raiseExceptionWithStatusCodeState(); |
||||
} catch(final RocksDBException e) { |
||||
assertThat(e.getStatus()).isNotNull(); |
||||
assertThat(e.getStatus().getCode()).isEqualTo(Code.NotSupported); |
||||
assertThat(e.getStatus().getSubCode()).isEqualTo(SubCode.None); |
||||
assertThat(e.getStatus().getState()).isNotNull(); |
||||
assertThat(e.getMessage()).isEqualTo("test message"); |
||||
return; |
||||
} |
||||
fail(); |
||||
} |
||||
|
||||
private native void raiseException() throws RocksDBException; |
||||
private native void raiseExceptionWithStatusCode() throws RocksDBException; |
||||
private native void raiseExceptionNoMsgWithStatusCode() throws RocksDBException; |
||||
private native void raiseExceptionWithStatusCodeSubCode() |
||||
throws RocksDBException; |
||||
private native void raiseExceptionNoMsgWithStatusCodeSubCode() |
||||
throws RocksDBException; |
||||
private native void raiseExceptionWithStatusCodeState() |
||||
throws RocksDBException; |
||||
} |
Loading…
Reference in new issue