use of com.cinchapi.concourse.thrift.ComplexTObject in project concourse by cinchapi.
the class RemoteInvocationThread method run.
@Override
public final void run() {
int argCount = request.args.size() + (useLocalThriftArgs ? 3 : 0);
Object[] jargs = new Object[argCount];
int i = 0;
for (; i < request.args.size(); ++i) {
Object jarg = request.args.get(i).getJavaObject();
if (jarg instanceof ByteBuffer) {
// If any of the arguments are BINARY, we assume that the caller
// manually serialized a PluginSerializable object, so we must
// try to convert to the actual object so that the method is
// actually called.
jarg = serializer().deserialize((ByteBuffer) jarg);
}
jargs[i] = jarg;
}
if (useLocalThriftArgs) {
jargs[i++] = request.creds;
jargs[i++] = request.transaction;
jargs[i++] = request.environment;
}
RemoteMethodResponse response = null;
try {
if (request.method.equals("getServerVersion")) {
// getServerVersion, for some reason doesn't take any
// arguments...not even the standard meta arguments that all
// other methods take
jargs = new Object[0];
}
Object result0 = Reflection.callIf((method) -> Modifier.isPublic(method.getModifiers()) && !Reflection.isDeclaredAnnotationPresentInHierarchy(method, PluginRestricted.class), invokable, request.method, jargs);
if (result0 instanceof PluginSerializable) {
// CON-509: PluginSerializable objects must be wrapped as BINARY
// within a ComplexTObject
result0 = serializer().serialize(result0);
}
ComplexTObject result = ComplexTObject.fromJavaObject(result0);
response = new RemoteMethodResponse(request.creds, result);
} catch (Exception e) {
e = (Exception) Throwables.getRootCause(e);
response = new RemoteMethodResponse(request.creds, e);
logger.error("Remote invocation error: {}", e, e);
}
ByteBuffer buffer = serializer().serialize(response);
outgoing.write(buffer);
}
use of com.cinchapi.concourse.thrift.ComplexTObject in project concourse by cinchapi.
the class ConcourseServer method invokeManagement.
@Override
@PluginRestricted
public ComplexTObject invokeManagement(String method, List<ComplexTObject> params, AccessToken creds) throws TException {
Object[] args = new Object[params.size() + 1];
for (int i = 0; i < params.size(); ++i) {
ComplexTObject arg = params.get(i);
args[i] = arg.getJavaObject();
}
args[args.length - 1] = creds;
try {
Object result = Reflection.callIf(invoked -> Reflection.isDeclaredAnnotationPresentInHierarchy(invoked, ClientInvokable.class), this, method, args);
return ComplexTObject.fromJavaObject(result);
} catch (IllegalStateException e) {
throw new ManagementException("The requested method invocation is either invalid or not " + "eligble for client-side invocation");
} catch (Exception e) {
throw new ManagementException(e.getMessage());
}
}
use of com.cinchapi.concourse.thrift.ComplexTObject in project concourse by cinchapi.
the class PluginSerializerTest method randomRemoteMessage.
/**
* Generate a random {@link RemoteMessage} for testing.
*
* @return a RemoteMessage
*/
private RemoteMessage randomRemoteMessage() {
int seed = Random.getInt();
RemoteMessage message;
if (seed % 3 == 0) {
message = Reflection.newInstance("com.cinchapi.concourse.server.plugin.RemoteAttributeExchange", Random.getString(), Random.getString());
} else if (seed % 2 == 0) {
AccessToken creds = new AccessToken(ByteBuffer.wrap(Random.getString().getBytes(StandardCharsets.UTF_8)));
TransactionToken transaction = new TransactionToken(creds, Time.now());
String method = Random.getSimpleString();
String environment = Random.getSimpleString();
int argsCount = Math.abs(Random.getInt()) % 8;
ComplexTObject[] args = new ComplexTObject[argsCount];
for (int i = 0; i < argsCount; ++i) {
args[i] = ComplexTObject.fromJavaObject(Random.getObject());
}
message = Reflection.newInstance("com.cinchapi.concourse.server.plugin.RemoteMethodRequest", method, creds, transaction, environment, args);
} else {
AccessToken creds = new AccessToken(ByteBuffer.wrap(Random.getString().getBytes(StandardCharsets.UTF_8)));
ComplexTObject response = ComplexTObject.fromJavaObject(Random.getObject());
message = Reflection.newInstance("com.cinchapi.concourse.server.plugin.RemoteMethodResponse", creds, response);
}
return message;
}
use of com.cinchapi.concourse.thrift.ComplexTObject in project concourse by cinchapi.
the class ConcourseThriftDriver method invokePlugin.
@Override
public <T> T invokePlugin(String id, String method, Object... args) {
return execute(() -> {
List<ComplexTObject> params = Lists.newArrayListWithCapacity(args.length);
for (Object arg : args) {
params.add(ComplexTObject.fromJavaObject(arg));
}
ComplexTObject result = core.invokePlugin(id, method, params, creds, transaction, environment);
return result.getJavaObject();
});
}
use of com.cinchapi.concourse.thrift.ComplexTObject in project concourse by cinchapi.
the class PluginSerializer method serialize.
/**
* Return a {@link ByteBuffer} that contains the serialized form of the
* input {@code object}.
*
* @param object the object to serialize
* @return the serialized form within a ByteBuffer
*/
public ByteBuffer serialize(Object object) {
ByteBuffer buffer = null;
if (object instanceof PluginSerializable) {
HeapBuffer buffer0 = HeapBuffer.allocate();
buffer0.writeByte(Scheme.PLUGIN_SERIALIZABLE.ordinal());
buffer0.writeUTF8(object.getClass().getName());
((PluginSerializable) object).serialize(buffer0);
byte[] bytes = new byte[(int) buffer0.position()];
buffer0.flip();
buffer0.read(bytes);
buffer = ByteBuffer.wrap(bytes);
return buffer;
} else if (object instanceof RemoteMessage) {
HeapBuffer buffer0 = (HeapBuffer) ((RemoteMessage) object).serialize();
buffer = ByteBuffer.allocate((int) buffer0.remaining() + 1);
buffer.put((byte) Scheme.REMOTE_MESSAGE.ordinal());
buffer.put(buffer0.array(), 0, (int) buffer0.remaining());
buffer.flip();
return buffer;
} else if (object instanceof ComplexTObject) {
byte[] bytes = ((ComplexTObject) object).toByteBuffer().array();
buffer = ByteBuffer.allocate(bytes.length + 1);
buffer.put((byte) Scheme.COMPLEX_TOBJECT.ordinal());
buffer.put(bytes);
buffer.flip();
return buffer;
} else if (object instanceof TObject) {
byte[] bytes = ((TObject) object).getData();
buffer = ByteBuffer.allocate(bytes.length + 2);
buffer.put((byte) Scheme.TOBJECT.ordinal());
buffer.put((byte) ((TObject) object).getType().ordinal());
buffer.put(bytes);
buffer.flip();
return buffer;
} else if (object instanceof String || object.getClass().isPrimitive() || object instanceof Number || object instanceof Boolean || object instanceof Map || object instanceof List || object instanceof Set) {
return serialize(ComplexTObject.fromJavaObject(object));
} else if (object instanceof Serializable) {
byte[] bytes = ByteBuffers.getByteArray(Serializables.getBytes((Serializable) object));
byte[] classBytes = object.getClass().getName().getBytes(StandardCharsets.UTF_8);
buffer = ByteBuffer.allocate(1 + 2 + classBytes.length + bytes.length);
buffer.put((byte) Scheme.JAVA_SERIALIZABLE.ordinal());
buffer.putShort((short) classBytes.length);
buffer.put(classBytes);
buffer.put(bytes);
buffer.flip();
return buffer;
} else {
throw new IllegalStateException("Cannot plugin serialize an object of type " + object.getClass());
}
}
Aggregations