com.mongodb.embedded.client.EmbeddedInternalConnection Maven / Gradle / Ivy
/*
* Copyright 2008-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.embedded.client;
import com.mongodb.MongoCompressor;
import com.mongodb.ServerAddress;
import com.mongodb.async.SingleResultCallback;
import com.mongodb.connection.AsyncCompletionHandler;
import com.mongodb.connection.ClusterId;
import com.mongodb.connection.ConnectionDescription;
import com.mongodb.connection.ServerId;
import com.mongodb.connection.Stream;
import com.mongodb.connection.StreamFactory;
import com.mongodb.event.CommandListener;
import com.mongodb.internal.connection.Authenticator;
import com.mongodb.internal.connection.CommandMessage;
import com.mongodb.internal.connection.InternalConnection;
import com.mongodb.internal.connection.InternalStreamConnection;
import com.mongodb.internal.connection.InternalStreamConnectionInitializer;
import com.mongodb.internal.connection.ResponseBuffers;
import com.mongodb.session.SessionContext;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import org.bson.BsonDocument;
import org.bson.ByteBuf;
import org.bson.ByteBufNIO;
import org.bson.codecs.Decoder;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class EmbeddedInternalConnection implements InternalConnection {
private final InternalConnection wrapped;
private volatile Pointer clientStatusPointer;
private volatile Pointer clientPointer;
EmbeddedInternalConnection(final Pointer instancePointer, final CommandListener commandListener,
final BsonDocument clientMetadataDocument) {
this.clientStatusPointer = MongoDBCAPIHelper.createStatusPointer();
this.clientPointer = MongoDBCAPIHelper.create_client(instancePointer, clientStatusPointer);
this.wrapped = new InternalStreamConnection(new ServerId(new ClusterId(), new ServerAddress()),
new StreamFactory() {
@Override
public Stream create(final ServerAddress serverAddress) {
return new EmbeddedInternalStream();
}
}, Collections.emptyList(), commandListener,
new InternalStreamConnectionInitializer(Collections.emptyList(), clientMetadataDocument,
Collections.emptyList()));
}
@Override
public ConnectionDescription getDescription() {
return wrapped.getDescription();
}
@Override
public void open() {
wrapped.open();
}
@Override
public void openAsync(final SingleResultCallback callback) {
wrapped.openAsync(callback);
}
@Override
public void close() {
if (!wrapped.isClosed()) {
wrapped.close();
MongoDBCAPIHelper.client_destroy(clientPointer, clientStatusPointer);
clientPointer = null;
MongoDBCAPIHelper.destroyStatusPointer(clientStatusPointer);
clientStatusPointer = null;
}
}
@Override
public boolean opened() {
return wrapped.opened();
}
@Override
public boolean isClosed() {
return wrapped.isClosed();
}
@Override
public T sendAndReceive(final CommandMessage message, final Decoder decoder, final SessionContext sessionContext) {
return wrapped.sendAndReceive(message, decoder, sessionContext);
}
@Override
public void sendAndReceiveAsync(final CommandMessage message, final Decoder decoder, final SessionContext sessionContext,
final SingleResultCallback callback) {
wrapped.sendAndReceiveAsync(message, decoder, sessionContext, callback);
}
@Override
public void sendMessage(final List byteBuffers, final int lastRequestId) {
wrapped.sendMessage(byteBuffers, lastRequestId);
}
@Override
public ResponseBuffers receiveMessage(final int responseTo) {
return wrapped.receiveMessage(responseTo);
}
@Override
public void sendMessageAsync(final List byteBuffers, final int lastRequestId, final SingleResultCallback callback) {
wrapped.sendMessageAsync(byteBuffers, lastRequestId, callback);
}
@Override
public void receiveMessageAsync(final int responseTo, final SingleResultCallback callback) {
wrapped.receiveMessageAsync(responseTo, callback);
}
@Override
public ByteBuf getBuffer(final int size) {
return wrapped.getBuffer(size);
}
class EmbeddedInternalStream implements Stream {
private volatile boolean isClosed;
private volatile ByteBuffer curResponse;
@Override
public void open() {
// nothing to do here
}
@Override
public void openAsync(final AsyncCompletionHandler handler) {
// nothing to do here
handler.completed(null);
}
@Override
public void write(final List buffers) {
byte[] message = createCompleteMessage(buffers);
PointerByReference outputBufferReference = new PointerByReference();
IntByReference outputSize = new IntByReference();
MongoDBCAPIHelper.client_invoke(clientPointer, message, outputBufferReference, outputSize, clientStatusPointer);
curResponse = outputBufferReference.getValue().getByteBuffer(0, outputSize.getValue());
}
@Override
public ByteBuf read(final int numBytes) {
ByteBuffer slice = curResponse.slice();
((Buffer) slice).limit(numBytes);
((Buffer) curResponse).position(((Buffer) curResponse).position() + numBytes);
return new ByteBufNIO(slice);
}
@Override
public void writeAsync(final List buffers, final AsyncCompletionHandler handler) {
throw new UnsupportedOperationException(getClass() + " does not support asynchronous operations.");
}
@Override
public void readAsync(final int numBytes, final AsyncCompletionHandler handler) {
throw new UnsupportedOperationException(getClass() + " does not support asynchronous operations.");
}
@Override
public ServerAddress getAddress() {
return wrapped.getDescription().getServerAddress();
}
@Override
public void close() {
isClosed = true;
}
@Override
public boolean isClosed() {
return isClosed;
}
@Override
public ByteBuf getBuffer(final int size) {
return new ByteBufNIO(ByteBuffer.wrap(new byte[size]));
}
private byte[] createCompleteMessage(final List byteBufList) {
List buffers = asByteBufferList(byteBufList);
int totalLength = 0;
for (ByteBuffer cur : buffers) {
totalLength += cur.remaining();
}
byte[] completeMessage = new byte[totalLength];
int offset = 0;
for (ByteBuffer cur : buffers) {
int remaining = cur.remaining();
cur.get(completeMessage, offset, cur.remaining());
offset += remaining;
}
return completeMessage;
}
private List asByteBufferList(final List byteBufList) {
List retVal = new ArrayList(byteBufList.size());
for (ByteBuf cur: byteBufList) {
retVal.add(cur.asNIO());
}
return retVal;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy