com.mongodb.crypt.capi.MongoCryptContextImpl Maven / Gradle / Ivy
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed 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 com.mongodb.crypt.capi;
import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t;
import com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_t;
import com.mongodb.crypt.capi.CAPI.mongocrypt_kms_ctx_t;
import org.bson.BsonDocument;
import org.bson.RawBsonDocument;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_destroy;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_new;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_destroy;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_finalize;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_kms_done;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_mongo_done;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_mongo_feed;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_mongo_op;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_next_kms_ctx;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_state;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_status;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_destroy;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_new;
import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_t;
import static com.mongodb.crypt.capi.CAPIHelper.toBinary;
import static com.mongodb.crypt.capi.CAPIHelper.toDocument;
import static org.bson.assertions.Assertions.isTrue;
import static org.bson.assertions.Assertions.notNull;
class MongoCryptContextImpl implements MongoCryptContext {
private final mongocrypt_ctx_t wrapped;
private volatile boolean closed;
MongoCryptContextImpl(final mongocrypt_ctx_t wrapped) {
notNull("wrapped", wrapped);
this.wrapped = wrapped;
}
@Override
public State getState() {
isTrue("open", !closed);
return State.fromIndex(mongocrypt_ctx_state(wrapped));
}
@Override
public RawBsonDocument getMongoOperation() {
isTrue("open", !closed);
mongocrypt_binary_t binary = mongocrypt_binary_new();
try {
boolean success = mongocrypt_ctx_mongo_op(wrapped, binary);
if (!success) {
throwExceptionFromStatus();
}
return toDocument(binary);
} finally {
mongocrypt_binary_destroy(binary);
}
}
@Override
public void addMongoOperationResult(final BsonDocument document) {
isTrue("open", !closed);
try (BinaryHolder binaryHolder = toBinary(document)) {
boolean success = mongocrypt_ctx_mongo_feed(wrapped, binaryHolder.getBinary());
if (!success) {
throwExceptionFromStatus();
}
}
}
@Override
public void completeMongoOperation() {
isTrue("open", !closed);
boolean success = mongocrypt_ctx_mongo_done(wrapped);
if (!success) {
throwExceptionFromStatus();
}
}
@Override
public MongoKeyDecryptor nextKeyDecryptor() {
isTrue("open", !closed);
mongocrypt_kms_ctx_t kmsContext = mongocrypt_ctx_next_kms_ctx(wrapped);
if (kmsContext == null) {
return null;
}
return new MongoKeyDecryptorImpl(kmsContext);
}
@Override
public void completeKeyDecryptors() {
isTrue("open", !closed);
boolean success = mongocrypt_ctx_kms_done(wrapped);
if (!success) {
throwExceptionFromStatus();
}
}
@Override
public RawBsonDocument finish() {
isTrue("open", !closed);
mongocrypt_binary_t binary = mongocrypt_binary_new();
try {
boolean success = mongocrypt_ctx_finalize(wrapped, binary);
if (!success) {
throwExceptionFromStatus();
}
return toDocument(binary);
} finally {
mongocrypt_binary_destroy(binary);
}
}
@Override
public void close() {
mongocrypt_ctx_destroy(wrapped);
closed = true;
}
static void throwExceptionFromStatus(final mongocrypt_ctx_t wrapped) {
mongocrypt_status_t status = mongocrypt_status_new();
mongocrypt_ctx_status(wrapped, status);
MongoCryptException e = new MongoCryptException(status);
mongocrypt_status_destroy(status);
throw e;
}
private void throwExceptionFromStatus() {
throwExceptionFromStatus(wrapped);
}
}