Search in sources :

Example 1 with PMessage

use of net.morimekta.providence.PMessage 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);
    }
}
Also used : PMessage(net.morimekta.providence.PMessage) PServiceCallType(net.morimekta.providence.PServiceCallType) IOException(java.io.IOException) PField(net.morimekta.providence.descriptor.PField) PApplicationException(net.morimekta.providence.PApplicationException) PServiceCall(net.morimekta.providence.PServiceCall) LittleEndianBinaryReader(net.morimekta.util.io.LittleEndianBinaryReader) PServiceMethod(net.morimekta.providence.descriptor.PServiceMethod) Nonnull(javax.annotation.Nonnull)

Example 2 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class FastBinarySerializer method writeContainerEntry.

@SuppressWarnings("unchecked")
private int writeContainerEntry(LittleEndianBinaryWriter out, int typeid, PDescriptor descriptor, Object value) throws IOException {
    switch(typeid) {
        case VARINT:
            {
                if (value instanceof Boolean) {
                    return out.writeVarint(((Boolean) value ? 1 : 0));
                } else if (value instanceof Number) {
                    return out.writeZigzag(((Number) value).longValue());
                } else if (value instanceof PEnumValue) {
                    return out.writeZigzag(((PEnumValue) value).asInteger());
                } else {
                    throw new SerializerException("");
                }
            }
        case FIXED_64:
            {
                return out.writeDouble((Double) value);
            }
        case BINARY:
            {
                if (value instanceof CharSequence) {
                    byte[] bytes = ((String) value).getBytes(StandardCharsets.UTF_8);
                    int len = out.writeVarint(bytes.length);
                    out.write(bytes);
                    return len + bytes.length;
                } else if (value instanceof Binary) {
                    Binary bytes = (Binary) value;
                    int len = out.writeVarint(bytes.length());
                    bytes.write(out);
                    return len + bytes.length();
                } else {
                    throw new SerializerException("");
                }
            }
        case MESSAGE:
            {
                return writeMessage(out, (PMessage) value);
            }
        case COLLECTION:
            {
                if (value instanceof Map) {
                    Map<Object, Object> map = (Map<Object, Object>) value;
                    PMap<?, ?> desc = (PMap<?, ?>) descriptor;
                    int ktype = itemType(desc.keyDescriptor());
                    int vtype = itemType(desc.itemDescriptor());
                    int len = out.writeVarint(map.size() * 2);
                    len += out.writeVarint(ktype << 3 | vtype);
                    for (Map.Entry<Object, Object> entry : map.entrySet()) {
                        len += writeContainerEntry(out, ktype, desc.keyDescriptor(), entry.getKey());
                        len += writeContainerEntry(out, vtype, desc.itemDescriptor(), entry.getValue());
                    }
                    return len;
                } else if (value instanceof Collection) {
                    Collection<Object> coll = (Collection<Object>) value;
                    PContainer<?> desc = (PContainer<?>) descriptor;
                    int vtype = itemType(desc.itemDescriptor());
                    int len = out.writeVarint(coll.size());
                    len += out.writeVarint(vtype);
                    for (Object item : coll) {
                        len += writeContainerEntry(out, vtype, desc.itemDescriptor(), item);
                    }
                    return len;
                } else {
                    throw new SerializerException("");
                }
            }
        default:
            throw new SerializerException("");
    }
}
Also used : PEnumValue(net.morimekta.providence.PEnumValue) PMap(net.morimekta.providence.descriptor.PMap) PMessage(net.morimekta.providence.PMessage) PContainer(net.morimekta.providence.descriptor.PContainer) Collection(java.util.Collection) Binary(net.morimekta.util.Binary) Map(java.util.Map) PMap(net.morimekta.providence.descriptor.PMap)

Example 3 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class SerializerTest method setUpData.

@BeforeClass
public static void setUpData() throws IOException, ExceptionFields {
    MessageGenerator gen = new MessageGenerator().addFactory(f -> {
        if (f.equals(Operand._Field.OPERATION)) {
            return () -> Operation.builder().setOperator(Operator.ADD).addToOperands(Operand.withNumber(123)).addToOperands(Operand.withNumber(321)).build();
        }
        return null;
    });
    if (operation == null) {
        operation = gen.generate(Operation.kDescriptor);
    }
    if (containers == null) {
        containers = new ArrayList<>();
        for (int i = 0; i < 1; ++i) {
            containers.add(gen.generate(Containers.kDescriptor));
        }
    }
    serviceCalls = new ArrayList<>();
    /**
     * Temporary setup needed to generate
     */
    ContainerService.Iface impl = pC -> {
        if (pC == null) {
            throw new PApplicationException("", PApplicationExceptionType.INTERNAL_ERROR);
        }
        if (pC.mutate().presentFields().isEmpty()) {
            throw gen.generate(ExceptionFields.kDescriptor);
        }
        return CompactFields.builder().setName("" + pC.hashCode()).setId(pC.hashCode()).build();
    };
    PProcessor processor = new ContainerService.Processor(impl);
    PServiceCallHandler handler = new PServiceCallHandler() {

        @Nullable
        @Override
        @SuppressWarnings("unchecked")
        public <Request extends PMessage<Request, RequestField>, Response extends PMessage<Response, ResponseField>, RequestField extends PField, ResponseField extends PField> PServiceCall<Response, ResponseField> handleCall(PServiceCall<Request, RequestField> call, PService service) throws IOException {
            serviceCalls.add(call);
            try {
                PServiceCall response = processor.handleCall(call, service);
                serviceCalls.add(response);
                return response;
            } catch (PApplicationException e) {
                PServiceCall ex = new PServiceCall(call.getMethod(), PServiceCallType.EXCEPTION, call.getSequence(), e);
                serviceCalls.add(ex);
                return ex;
            }
        }
    };
    ContainerService.Client client = new ContainerService.Client(handler);
    client.load(gen.generate(Containers.kDescriptor));
    try {
        client.load(Containers.builder().build());
    } catch (ExceptionFields e) {
    // ignore.
    }
    try {
        // NPE -> PApplicationException
        client.load(null);
    } catch (PApplicationException e) {
    // ignore.
    }
}
Also used : Operand(net.morimekta.test.providence.core.calculator.Operand) CoreMatchers.is(org.hamcrest.CoreMatchers.is) BeforeClass(org.junit.BeforeClass) ByteArrayOutputStream(java.io.ByteArrayOutputStream) PApplicationException(net.morimekta.providence.PApplicationException) MessageCollectors(net.morimekta.providence.streams.MessageCollectors) EqualToMessage(net.morimekta.providence.util_internal.EqualToMessage) Binary(net.morimekta.util.Binary) PServiceCallType(net.morimekta.providence.PServiceCallType) ArrayList(java.util.ArrayList) Assert.assertThat(org.junit.Assert.assertThat) PService(net.morimekta.providence.descriptor.PService) Containers(net.morimekta.test.providence.core.Containers) PProcessor(net.morimekta.providence.PProcessor) ByteArrayInputStream(java.io.ByteArrayInputStream) PApplicationExceptionType(net.morimekta.providence.PApplicationExceptionType) MessageGenerator(net.morimekta.providence.util_internal.MessageGenerator) Assert.fail(org.junit.Assert.fail) Nullable(javax.annotation.Nullable) ExtraMatchers.equalToLines(net.morimekta.testing.ExtraMatchers.equalToLines) Operation(net.morimekta.test.providence.core.calculator.Operation) UTF_8(java.nio.charset.StandardCharsets.UTF_8) PServiceCallHandler(net.morimekta.providence.PServiceCallHandler) Test(org.junit.Test) IOException(java.io.IOException) MessageStreams(net.morimekta.providence.streams.MessageStreams) ContainerService(net.morimekta.test.providence.core.ContainerService) Collectors(java.util.stream.Collectors) File(java.io.File) PMessage(net.morimekta.providence.PMessage) PField(net.morimekta.providence.descriptor.PField) CompactFields(net.morimekta.test.providence.core.CompactFields) List(java.util.List) Rule(org.junit.Rule) PServiceCall(net.morimekta.providence.PServiceCall) ExceptionFields(net.morimekta.test.providence.core.ExceptionFields) TokenizerException(net.morimekta.providence.serializer.pretty.TokenizerException) ConsumeAll(net.morimekta.test.providence.core.ConsumeAll) Assert.assertEquals(org.junit.Assert.assertEquals) Operator(net.morimekta.test.providence.core.calculator.Operator) InputStream(java.io.InputStream) PProcessor(net.morimekta.providence.PProcessor) MessageGenerator(net.morimekta.providence.util_internal.MessageGenerator) PField(net.morimekta.providence.descriptor.PField) PProcessor(net.morimekta.providence.PProcessor) ExceptionFields(net.morimekta.test.providence.core.ExceptionFields) PServiceCallHandler(net.morimekta.providence.PServiceCallHandler) PMessage(net.morimekta.providence.PMessage) PApplicationException(net.morimekta.providence.PApplicationException) PServiceCall(net.morimekta.providence.PServiceCall) ContainerService(net.morimekta.test.providence.core.ContainerService) PService(net.morimekta.providence.descriptor.PService) BeforeClass(org.junit.BeforeClass)

Example 4 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class HasFieldValue method describeMismatch.

@Override
public void describeMismatch(Object o, Description mismatchDescription) {
    if (o == null) {
        mismatchDescription.appendText("got null message");
    } else {
        if (!(o instanceof PMessage)) {
            mismatchDescription.appendText("instance is not a message");
            return;
        }
        List<String> stack = new ArrayList<>();
        for (int i = 0; i < path.length; ++i) {
            stack.add(path[i]);
            String path = Strings.join(".", stack);
            if (!(o instanceof PMessage)) {
                mismatchDescription.appendText("field \'" + path + "\' is not a message");
                return;
            }
            PMessage actual = (PMessage) o;
            PField field = actual.descriptor().findFieldByName(this.path[i]);
            if (field == null) {
                mismatchDescription.appendText("field path \'" + path + "\' is not valid");
                return;
            }
            if (!actual.has(field.getId())) {
                mismatchDescription.appendText("field \'" + path + "\' is missing");
                return;
            }
            o = actual.get(field.getId());
        }
    }
}
Also used : PField(net.morimekta.providence.descriptor.PField) PMessage(net.morimekta.providence.PMessage) ArrayList(java.util.ArrayList)

Example 5 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class HasFieldValue method matches.

@Override
public boolean matches(Object o) {
    if (o == null) {
        return false;
    }
    for (int i = 0; i < path.length; ++i) {
        if (!(o instanceof PMessage)) {
            return false;
        }
        PMessage actual = (PMessage) o;
        PField field = actual.descriptor().findFieldByName(path[i]);
        if (field == null) {
            return false;
        }
        if (!actual.has(field.getId())) {
            return false;
        }
        o = actual.get(field.getId());
    }
    return true;
}
Also used : PField(net.morimekta.providence.descriptor.PField) PMessage(net.morimekta.providence.PMessage)

Aggregations

PMessage (net.morimekta.providence.PMessage)31 PField (net.morimekta.providence.descriptor.PField)20 Nonnull (javax.annotation.Nonnull)7 TokenizerException (net.morimekta.providence.serializer.pretty.TokenizerException)7 IOException (java.io.IOException)6 PEnumValue (net.morimekta.providence.PEnumValue)6 PServiceCall (net.morimekta.providence.PServiceCall)6 PServiceCallType (net.morimekta.providence.PServiceCallType)6 Token (net.morimekta.providence.serializer.pretty.Token)6 Map (java.util.Map)5 PApplicationException (net.morimekta.providence.PApplicationException)5 PMessageDescriptor (net.morimekta.providence.descriptor.PMessageDescriptor)5 SerializerException (net.morimekta.providence.serializer.SerializerException)5 Binary (net.morimekta.util.Binary)5 ArrayList (java.util.ArrayList)4 PMessageBuilder (net.morimekta.providence.PMessageBuilder)4 PServiceMethod (net.morimekta.providence.descriptor.PServiceMethod)4 TMessage (org.apache.thrift.protocol.TMessage)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3