use of net.morimekta.providence.PMessage 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;
}
}
use of net.morimekta.providence.PMessage in project providence by morimekta.
the class TTupleProtocolSerializer method readMessage.
private <Message extends PMessage<Message, Field>, Field extends PField> Message readMessage(TTupleProtocol protocol, PMessageDescriptor<Message, Field> descriptor) throws SerializerException, TException {
PMessageBuilder<Message, Field> builder = descriptor.builder();
if (descriptor.getVariant() == PMessageVariant.UNION) {
int fieldId = protocol.readI16();
PField fld = descriptor.findFieldById(fieldId);
if (fld != null) {
builder.set(fld.getId(), readTypedValue(fld.getDescriptor(), protocol));
} else {
throw new SerializerException("Unable to read unknown union field " + fieldId + " in " + descriptor.getQualifiedName());
}
} else {
PField[] fields = descriptor.getFields();
int numOptionals = countOptionals(fields);
BitSet optionals = null;
int optionalPos = 0;
for (PField fld : fields) {
if (fld.getRequirement() == PRequirement.REQUIRED) {
builder.set(fld.getId(), readTypedValue(fld.getDescriptor(), protocol));
} else {
if (optionals == null) {
optionals = protocol.readBitSet(numOptionals);
}
if (optionals.get(optionalPos)) {
builder.set(fld.getId(), readTypedValue(fld.getDescriptor(), protocol));
}
++optionalPos;
}
}
}
if (strict) {
try {
builder.validate();
} catch (IllegalStateException e) {
throw new SerializerException(e, e.getMessage());
}
}
return builder.build();
}
use of net.morimekta.providence.PMessage in project providence by morimekta.
the class TTupleProtocolSerializer 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 {
TMessage tm = null;
PServiceCallType type = null;
try {
TTransport transport = new TIOStreamTransport(input);
TTupleProtocol protocol = (TTupleProtocol) protocolFactory.getProtocol(transport);
tm = protocol.readMessageBegin();
type = PServiceCallType.findById(tm.type);
if (type == null) {
throw new SerializerException("Unknown call type for id " + tm.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());
}
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, "Unable to serialize into transport protocol").setExceptionType(PApplicationExceptionType.findById(e.getType())).setCallType(type).setMethodName(tm != null ? tm.name : "").setSequenceNo(tm != null ? tm.seqid : 0);
} catch (TException e) {
throw new SerializerException(e, "Transport exception in protocol").setExceptionType(PApplicationExceptionType.PROTOCOL_ERROR).setCallType(type).setMethodName(tm != null ? tm.name : "").setSequenceNo(tm != null ? tm.seqid : 0);
}
}
use of net.morimekta.providence.PMessage in project providence by morimekta.
the class TProtocolSerializerTest method assertConsistent.
@SuppressWarnings("unchecked")
public <Providence extends PMessage<Providence, ProvidenceField>, ProvidenceField extends PField, Thrift extends TBase<Thrift, ThriftField>, ThriftField extends TFieldIdEnum> void assertConsistent(String prefix, Providence providence, Thrift thrift) {
if (providence.descriptor().getVariant() == PMessageVariant.UNION) {
TUnion<?, ThriftField> t_union = (TUnion) thrift;
PUnion<?, ProvidenceField> p_union = (PUnion) providence;
ThriftField t_field = t_union.getSetField();
PField p_field = p_union.unionField();
assertEquals(p_field.getId(), t_field.getThriftFieldId());
} else {
for (PField field : providence.descriptor().getFields()) {
ThriftField thriftField = thrift.fieldForId(field.getId());
String fieldPath = (prefix.isEmpty() ? "" : prefix + ".") + field.getName();
assertEquals("has " + fieldPath, providence.has(field.getId()), thrift.isSet(thriftField));
if (providence.has(field.getId())) {
switch(field.getType()) {
case MESSAGE:
assertConsistent(fieldPath, (PMessage) providence.get(field.getId()), (TBase) thrift.getFieldValue(thriftField));
break;
case ENUM:
{
PEnumValue<?> pe = providence.get(field.getId());
TEnum te = (TEnum) thrift.getFieldValue(thriftField);
assertEquals(fieldPath, pe.asInteger(), te.getValue());
break;
}
case BINARY:
{
Binary pBin = providence.get(field.getId());
byte[] tBytes = (byte[]) thrift.getFieldValue(thriftField);
Binary tBin = Binary.wrap(tBytes);
assertEquals(fieldPath, pBin, tBin);
break;
}
case MAP:
{
Map pm = providence.get(field.getId());
Map tm = (Map) thrift.getFieldValue(thriftField);
assertEquals(fieldPath + " size", pm.size(), tm.size());
// TODO: Compare actual content.
break;
}
case SET:
{
Set ps = providence.get(field.getId());
Set ts = (Set) thrift.getFieldValue(thriftField);
assertEquals(fieldPath + " size", ps.size(), ts.size());
// TODO: Compare actual content.
break;
}
case LIST:
{
List pl = providence.get(field.getId());
List tl = (List) thrift.getFieldValue(thriftField);
assertEquals(fieldPath + " size", pl.size(), tl.size());
for (int i = 0; i < pl.size(); ++i) {
String itemPath = fieldPath + "[" + i + "]";
Object pi = pl.get(i);
Object ti = tl.get(i);
if (pi instanceof PMessage) {
assertConsistent(itemPath, (PMessage) pi, (TBase) ti);
} else if (pi instanceof Set) {
// TODO: Compare actual content.
} else if (pi instanceof List) {
// TODO: Compare actual content.
} else if (pi instanceof Map) {
// TODO: Compare actual content.
} else if (pi instanceof Binary) {
Binary pb = (Binary) pi;
Binary tb = Binary.wrap(((ByteBuffer) ti).array());
assertEquals(itemPath, pb, tb);
} else if (pi instanceof PEnumValue) {
PEnumValue pe = (PEnumValue) pi;
TEnum te = (TEnum) ti;
assertEquals(itemPath, pe.asInteger(), te.getValue());
} else {
assertEquals(itemPath, pi, ti);
}
}
break;
}
default:
assertEquals(fieldPath, providence.get(field.getId()), thrift.getFieldValue(thriftField));
break;
}
}
}
}
}
use of net.morimekta.providence.PMessage in project providence by morimekta.
the class Resolve method execute.
@Override
@SuppressWarnings("unchecked")
public void execute(ProvidenceConfig config) throws IOException {
if (files.isEmpty()) {
throw new IllegalArgumentException("No config files to resolve");
}
PMessage message = null;
for (File configFile : files) {
if (message == null) {
message = config.getConfig(configFile);
} else {
message = (PMessage) config.getConfig(configFile, message);
}
}
serializer.serialize(System.out, message);
System.out.println();
}
Aggregations