use of net.morimekta.providence.PServiceCallType in project providence by morimekta.
the class FastBinarySerializer method deserialize.
@Nonnull
@Override
@SuppressWarnings("unchecked")
public <Message extends PMessage<Message, Field>, Field extends PField> PServiceCall<Message, Field> deserialize(@Nonnull InputStream is, @Nonnull PService service) throws SerializerException {
String methodName = null;
int sequence = 0;
PServiceCallType type = null;
try {
LittleEndianBinaryReader in = new LittleEndianBinaryReader(is);
// Max method name length: 255 chars.
int tag = in.readIntVarint();
int len = tag >>> 3;
int typeKey = tag & 0x07;
methodName = new String(in.expectBytes(len), UTF_8);
sequence = in.readIntVarint();
type = PServiceCallType.findById(typeKey);
if (type == null) {
throw new SerializerException("Invalid call type " + typeKey).setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
} else if (type == PServiceCallType.EXCEPTION) {
PApplicationException ex = readMessage(in, PApplicationException.kDescriptor);
return (PServiceCall<Message, Field>) new PServiceCall<>(methodName, type, sequence, ex);
}
PServiceMethod method = service.getMethod(methodName);
if (method == null) {
throw new SerializerException("No such method %s on %s", methodName, service.getQualifiedName()).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
}
@SuppressWarnings("unchecked") PMessageDescriptor<Message, Field> descriptor = isRequestCallType(type) ? method.getRequestType() : method.getResponseType();
if (descriptor == null) {
throw new SerializerException("No such %s descriptor for %s", isRequestCallType(type) ? "request" : "response", service.getQualifiedName()).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
}
Message message = readMessage(in, descriptor);
return new PServiceCall<>(methodName, type, sequence, message);
} catch (SerializerException e) {
throw new SerializerException(e).setCallType(type).setMethodName(methodName).setSequenceNo(sequence);
} catch (IOException e) {
throw new SerializerException(e, e.getMessage()).setCallType(type).setMethodName(methodName).setSequenceNo(sequence);
}
}
use of net.morimekta.providence.PServiceCallType in project providence by morimekta.
the class JsonSerializer method parseServiceCall.
@SuppressWarnings("unchecked")
private <T extends PMessage<T, F>, F extends PField> PServiceCall<T, F> parseServiceCall(JsonTokenizer tokenizer, PService service) throws IOException {
PServiceCallType type = null;
String methodName = null;
int sequence = 0;
try {
tokenizer.expectSymbol("service call start", JsonToken.kListStart);
methodName = tokenizer.expectString("method name").rawJsonLiteral();
tokenizer.expectSymbol("entry sep", JsonToken.kListSep);
JsonToken callTypeToken = tokenizer.expect("call type");
if (callTypeToken.isInteger()) {
int typeKey = callTypeToken.byteValue();
type = PServiceCallType.findById(typeKey);
if (type == null) {
throw new SerializerException("Service call type " + typeKey + " is not valid").setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
}
} else if (callTypeToken.isLiteral()) {
String typeName = callTypeToken.rawJsonLiteral();
type = PServiceCallType.findByName(typeName.toUpperCase(Locale.US));
if (type == null) {
throw new SerializerException("Service call type \"" + Strings.escape(typeName) + "\" is not valid").setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
}
} else {
throw new SerializerException("Invalid service call type token " + callTypeToken.asString()).setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
}
tokenizer.expectSymbol("entry sep", JsonToken.kListSep);
sequence = tokenizer.expectNumber("Service call sequence").intValue();
tokenizer.expectSymbol("entry sep", JsonToken.kListSep);
if (type == PServiceCallType.EXCEPTION) {
PApplicationException ex = (PApplicationException) parseTypedValue(tokenizer.expect("Message start"), tokenizer, PApplicationException.kDescriptor, false);
tokenizer.expectSymbol("service call end", JsonToken.kListEnd);
return (PServiceCall<T, F>) new PServiceCall<>(methodName, type, sequence, ex);
}
PServiceMethod method = service.getMethod(methodName);
if (method == null) {
throw new SerializerException("No such method " + methodName + " on " + service.getQualifiedName()).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
}
@SuppressWarnings("unchecked") PMessageDescriptor<T, F> descriptor = isRequestCallType(type) ? method.getRequestType() : method.getResponseType();
if (descriptor == null) {
throw new SerializerException("No %s type for %s.%s()", isRequestCallType(type) ? "request" : "response", service.getQualifiedName(), methodName).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
}
T message = (T) parseTypedValue(tokenizer.expect("message start"), tokenizer, descriptor, false);
tokenizer.expectSymbol("service call end", JsonToken.kListEnd);
return new PServiceCall<>(methodName, type, sequence, message);
} catch (SerializerException se) {
throw new SerializerException(se).setMethodName(methodName).setCallType(type).setSequenceNo(sequence);
} catch (JsonException je) {
throw new JsonSerializerException(je).setMethodName(methodName).setCallType(type).setSequenceNo(sequence);
}
}
use of net.morimekta.providence.PServiceCallType in project providence by morimekta.
the class PrettySerializer method deserialize.
@Nonnull
@Override
@SuppressWarnings("unchecked")
public <Message extends PMessage<Message, Field>, Field extends PField> PServiceCall<Message, Field> deserialize(@Nonnull InputStream input, @Nonnull PService service) throws IOException {
String methodName = null;
int sequence = 0;
PServiceCallType callType = null;
try {
// pretty printed service calls cannot be chained-serialized, so this should be totally safe.
Tokenizer tokenizer = new Tokenizer(input);
Token token = tokenizer.expect("Sequence or type");
if (token.isInteger()) {
sequence = (int) token.parseInteger();
tokenizer.expectSymbol("Sequence type sep", Token.kKeyValueSep);
token = tokenizer.expectIdentifier("Call Type");
}
callType = PServiceCallType.findByName(token.asString().toUpperCase(Locale.US));
if (callType == null) {
throw new TokenizerException(token, "No such call type %s", token.asString()).setLine(tokenizer.getLine()).setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
}
token = tokenizer.expectIdentifier("method name");
methodName = token.asString();
PServiceMethod method = service.getMethod(methodName);
if (method == null) {
throw new TokenizerException(token, "no such method %s on service %s", methodName, service.getQualifiedName()).setLine(tokenizer.getLine()).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
}
tokenizer.expectSymbol("call params start", Token.kParamsStart);
Message message;
switch(callType) {
case CALL:
case ONEWAY:
message = (Message) readMessage(tokenizer, method.getRequestType(), true);
break;
case REPLY:
message = (Message) readMessage(tokenizer, method.getResponseType(), true);
break;
case EXCEPTION:
message = (Message) readMessage(tokenizer, PApplicationException.kDescriptor, true);
break;
default:
throw new IllegalStateException("Unreachable code reached");
}
return new PServiceCall<>(methodName, callType, sequence, message);
} catch (TokenizerException e) {
e.setCallType(callType).setSequenceNo(sequence).setMethodName(methodName);
throw e;
} catch (IOException e) {
throw new SerializerException(e, e.getMessage()).setCallType(callType).setSequenceNo(sequence).setMethodName(methodName);
}
}
use of net.morimekta.providence.PServiceCallType in project providence by morimekta.
the class BinarySerializer method deserialize.
@Nonnull
@Override
@SuppressWarnings("unchecked")
public <Message extends PMessage<Message, Field>, Field extends PField> PServiceCall<Message, Field> deserialize(@Nonnull InputStream is, @Nonnull PService service) throws IOException {
BigEndianBinaryReader in = new BigEndianBinaryReader(is);
String methodName = null;
int sequence = 0;
PServiceCallType type = null;
try {
int methodNameLen = in.expectInt();
int typeKey;
// versioned
if (methodNameLen <= 0) {
int version = methodNameLen & VERSION_MASK;
if (version == VERSION_1) {
typeKey = methodNameLen & 0xFF;
methodNameLen = in.expectInt();
if (methodNameLen > MAX_METHOD_NAME_LEN) {
throw new SerializerException("Exceptionally long method name of %s bytes", methodNameLen).setExceptionType(PApplicationExceptionType.PROTOCOL_ERROR);
}
if (methodNameLen < 1) {
throw new SerializerException("Exceptionally short method name of %s bytes", methodNameLen).setExceptionType(PApplicationExceptionType.PROTOCOL_ERROR);
}
methodName = new String(in.expectBytes(methodNameLen), UTF_8);
} else {
throw new SerializerException("Bad protocol version: %08x", version >>> 16).setExceptionType(PApplicationExceptionType.INVALID_PROTOCOL);
}
} else {
if (strict && versioned) {
throw new SerializerException("Missing protocol version").setExceptionType(PApplicationExceptionType.INVALID_PROTOCOL);
}
if (methodNameLen > MAX_METHOD_NAME_LEN) {
if (methodNameLen >>> 24 == '<') {
throw new SerializerException("Received HTML in service call").setExceptionType(PApplicationExceptionType.PROTOCOL_ERROR);
}
if (methodNameLen >>> 24 == '{' || methodNameLen >>> 24 == '[') {
throw new SerializerException("Received JSON in service call").setExceptionType(PApplicationExceptionType.PROTOCOL_ERROR);
}
throw new SerializerException("Exceptionally long method name of %s bytes", methodNameLen).setExceptionType(PApplicationExceptionType.PROTOCOL_ERROR);
}
methodName = new String(in.expectBytes(methodNameLen), UTF_8);
typeKey = in.expectByte();
}
sequence = in.expectInt();
type = PServiceCallType.findById(typeKey);
PServiceMethod method = service.getMethod(methodName);
if (type == null) {
throw new SerializerException("Invalid call type " + typeKey).setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
} else if (type == PServiceCallType.EXCEPTION) {
PApplicationException ex = readMessage(in, PApplicationException.kDescriptor, strict);
return (PServiceCall<Message, Field>) new PServiceCall<>(methodName, type, sequence, ex);
} else if (method == null) {
throw new SerializerException("No such method " + methodName + " on " + service.getQualifiedName()).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
}
@SuppressWarnings("unchecked") PMessageDescriptor<Message, Field> descriptor = isRequestCallType(type) ? method.getRequestType() : method.getResponseType();
Message message = readMessage(in, descriptor, strict);
return new PServiceCall<>(methodName, type, sequence, message);
} catch (SerializerException se) {
throw new SerializerException(se).setMethodName(methodName).setCallType(type).setSequenceNo(sequence);
} catch (IOException e) {
throw new SerializerException(e, e.getMessage()).setMethodName(methodName).setCallType(type).setSequenceNo(sequence);
}
}
use of net.morimekta.providence.PServiceCallType in project providence by morimekta.
the class TProtocolSerializer method deserialize.
@Nonnull
@Override
@SuppressWarnings("unchecked")
public <Message extends PMessage<Message, Field>, Field extends PField> PServiceCall<Message, Field> deserialize(@Nonnull InputStream input, @Nonnull PService service) throws SerializerException {
PServiceCallType type = null;
TMessage tm = null;
try {
TTransport transport = new TIOStreamTransport(input);
TProtocol protocol = protocolFactory.getProtocol(transport);
tm = protocol.readMessageBegin();
type = PServiceCallType.findById(tm.type);
if (type == null) {
throw new SerializerException("Unknown call type for id " + tm.type).setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
} else if (type == PServiceCallType.EXCEPTION) {
PApplicationException exception = readMessage(protocol, PApplicationException.kDescriptor);
return new PServiceCall(tm.name, type, tm.seqid, exception);
}
PServiceMethod method = service.getMethod(tm.name);
if (method == null) {
throw new SerializerException("No such method " + tm.name + " on " + service.getQualifiedName()).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
}
@SuppressWarnings("unchecked") PMessageDescriptor<Message, Field> descriptor = isRequestCallType(type) ? method.getRequestType() : method.getResponseType();
Message message = readMessage(protocol, descriptor);
protocol.readMessageEnd();
return new PServiceCall<>(tm.name, type, tm.seqid, message);
} catch (TTransportException e) {
throw new SerializerException(e, e.getMessage()).setExceptionType(PApplicationExceptionType.findById(e.getType())).setCallType(type).setSequenceNo(tm != null ? tm.seqid : 0).setMethodName(tm != null ? tm.name : null);
} catch (TException e) {
throw new SerializerException(e, e.getMessage()).setExceptionType(PApplicationExceptionType.PROTOCOL_ERROR).setCallType(type).setSequenceNo(tm != null ? tm.seqid : 0).setMethodName(tm != null ? tm.name : null);
} catch (SerializerException e) {
e.setMethodName(tm.name).setSequenceNo(tm.seqid).setCallType(type);
throw e;
}
}
Aggregations