Search in sources :

Example 11 with PServiceCall

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

the class QueuedFileMessageWriterTest method testAFewWrites_serviceCalls.

@Test
@SuppressWarnings("unchecked")
public void testAFewWrites_serviceCalls() throws IOException, InterruptedException {
    setDefaultPollDelay(new Duration(10, TimeUnit.MILLISECONDS));
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    IOMessageWriter target = new IOMessageWriter(baos, new BinarySerializer());
    QueuedMessageWriter writer = new QueuedMessageWriter(target);
    ExecutorService executorService = Executors.newFixedThreadPool(11);
    for (int i = 0; i < 10; ++i) {
        executorService.submit(() -> {
            MessageGenerator generator = new MessageGenerator();
            for (int j = 0; j < 10; ++j) {
                try {
                    if (j > 0)
                        sleep(1L);
                    PServiceCall tmp = new PServiceCall("test", PServiceCallType.CALL, j, generator.generate(CompactFields.kDescriptor));
                    writer.write(tmp);
                } catch (IOException e) {
                    throw new UncheckedIOException(e.getMessage(), e);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }
    sleep(10L);
    executorService.shutdown();
    assertTrue(executorService.awaitTermination(10, TimeUnit.SECONDS));
    sleep(1L);
    writer.close();
}
Also used : MessageGenerator(net.morimekta.providence.util_internal.MessageGenerator) Duration(org.awaitility.Duration) UncheckedIOException(java.io.UncheckedIOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) PServiceCall(net.morimekta.providence.PServiceCall) ExecutorService(java.util.concurrent.ExecutorService) BinarySerializer(net.morimekta.providence.serializer.BinarySerializer) Test(org.junit.Test)

Example 12 with PServiceCall

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

the class BinarySerializerTest method testService.

@Test
public void testService() throws IOException, CalculateException {
    PServiceCall call = decode("[\"calculate\", \"call\", 44, {\"1\": {\"1\": 2}}]".getBytes(UTF_8), json);
    PServiceCall result = decode(encode(call, unversioned), lenient);
    assertThat(result, is(call));
    result = decode(encode(call, strict), strict);
    assertThat(result, is(call));
}
Also used : PServiceCall(net.morimekta.providence.PServiceCall) Test(org.junit.Test)

Example 13 with PServiceCall

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

the class WrappedProcessorTest method testWrapper.

@Test
public void testWrapper() throws IOException {
    PProcessor processor = mock(PProcessor.class);
    WrappedProcessor wrap = new WrappedProcessor(processor, (call, p) -> {
        // before call
        PServiceCall reply = p.handleCall(call, p.getDescriptor());
        // after call
        return reply;
    });
    PApplicationException c = new PApplicationException("call", PApplicationExceptionType.INTERNAL_ERROR);
    PApplicationException r = new PApplicationException("call", PApplicationExceptionType.INTERNAL_ERROR);
    AtomicReference<PService> service = new AtomicReference<>();
    service.set(new PService("test", "Service", service::get, new PServiceMethod[] {}) {

        @Nullable
        @Override
        public PServiceMethod getMethod(String name) {
            for (PServiceMethod method : getMethods()) {
                if (method.getName().equals(name)) {
                    return method;
                }
            }
            return null;
        }
    });
    PServiceCall call = new PServiceCall<>("test", PServiceCallType.CALL, 44, c);
    PServiceCall reply = new PServiceCall<>("reply", PServiceCallType.REPLY, 44, r);
    when(processor.getDescriptor()).thenReturn(service.get());
    when(processor.handleCall(call, service.get())).thenReturn(reply);
    assertThat(wrap.handleCall(call), sameInstance(reply));
    verify(processor, atLeastOnce()).getDescriptor();
    verify(processor).handleCall(call, service.get());
    verifyNoMoreInteractions(processor);
}
Also used : PProcessor(net.morimekta.providence.PProcessor) PServiceCall(net.morimekta.providence.PServiceCall) PApplicationException(net.morimekta.providence.PApplicationException) AtomicReference(java.util.concurrent.atomic.AtomicReference) PServiceMethod(net.morimekta.providence.descriptor.PServiceMethod) Nullable(javax.annotation.Nullable) PService(net.morimekta.providence.descriptor.PService) Test(org.junit.Test)

Example 14 with PServiceCall

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

Example 15 with PServiceCall

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

the class NonblockingSocketClientHandler method handleCall.

@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 {
    if (call.getType() == PServiceCallType.EXCEPTION || call.getType() == PServiceCallType.REPLY) {
        throw new PApplicationException("Request with invalid call type: " + call.getType(), PApplicationExceptionType.INVALID_MESSAGE_TYPE);
    }
    long startTime = System.nanoTime();
    PServiceCall<Response, ResponseField> response = null;
    CompletableFuture<PServiceCall> responseFuture = null;
    if (call.getType() == PServiceCallType.CALL) {
        responseFuture = new CompletableFuture<>();
        // Each sequence No must be unique for the client, otherwise this will be messed up.
        responseFutures.put(call.getSequence(), responseFuture);
    }
    try {
        synchronized (this) {
            try {
                ensureConnected(service);
                if (out == null) {
                    throw new IOException("Closed channel");
                }
                serializer.serialize(out, call);
                out.flush();
            } finally {
                if (out != null) {
                    out.completeFrame();
                }
            }
        }
        if (responseFuture != null) {
            try {
                if (response_timeout > 0) {
                    response = (PServiceCall<Response, ResponseField>) responseFuture.get(response_timeout, TimeUnit.MILLISECONDS);
                } else {
                    response = (PServiceCall<Response, ResponseField>) responseFuture.get();
                }
                long endTime = System.nanoTime();
                double duration = ((double) (endTime - startTime)) / NS_IN_MILLIS;
                try {
                    instrumentation.onComplete(duration, call, response);
                } catch (Exception ignore) {
                }
                return response;
            } catch (TimeoutException | InterruptedException e) {
                responseFuture.completeExceptionally(e);
                throw new IOException(e.getMessage(), e);
            } catch (ExecutionException e) {
                throw new IOException(e.getMessage(), e);
            } finally {
                responseFutures.remove(call.getSequence());
            }
        }
    } catch (Exception e) {
        long endTime = System.nanoTime();
        double duration = ((double) (endTime - startTime)) / NS_IN_MILLIS;
        try {
            instrumentation.onTransportException(e, duration, call, response);
        } catch (Exception ie) {
            e.addSuppressed(ie);
        }
        throw e;
    }
    return null;
}
Also used : IOException(java.io.IOException) PApplicationException(net.morimekta.providence.PApplicationException) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) PApplicationException(net.morimekta.providence.PApplicationException) PServiceCall(net.morimekta.providence.PServiceCall) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

PServiceCall (net.morimekta.providence.PServiceCall)19 IOException (java.io.IOException)13 PApplicationException (net.morimekta.providence.PApplicationException)12 PServiceCallType (net.morimekta.providence.PServiceCallType)7 PServiceMethod (net.morimekta.providence.descriptor.PServiceMethod)7 Nonnull (javax.annotation.Nonnull)6 PMessage (net.morimekta.providence.PMessage)6 SerializerException (net.morimekta.providence.serializer.SerializerException)6 UncheckedIOException (java.io.UncheckedIOException)5 PField (net.morimekta.providence.descriptor.PField)5 Test (org.junit.Test)5 PProcessor (net.morimekta.providence.PProcessor)4 PService (net.morimekta.providence.descriptor.PService)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 ExecutionException (java.util.concurrent.ExecutionException)2 ExecutorService (java.util.concurrent.ExecutorService)2 TimeoutException (java.util.concurrent.TimeoutException)2 Nullable (javax.annotation.Nullable)2 PServiceCallHandler (net.morimekta.providence.PServiceCallHandler)2