use of net.morimekta.providence.PProcessor 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.
}
}
use of net.morimekta.providence.PProcessor 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);
}
use of net.morimekta.providence.PProcessor in project providence by morimekta.
the class ProvidenceServlet method doPost.
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
long startTime = System.nanoTime();
AtomicReference<PServiceCall> callRef = new AtomicReference<>();
AtomicReference<PServiceCall> responseRef = new AtomicReference<>();
PProcessor processor = new WrappedProcessor(processorProvider.processorForRequest(req), (c, r) -> {
callRef.set(c);
responseRef.set(r.handleCall(c));
return responseRef.get();
});
try {
Serializer requestSerializer = serializerProvider.getDefault();
if (req.getContentType() != null) {
try {
MediaType mediaType = MediaType.parse(req.getContentType());
requestSerializer = serializerProvider.getSerializer(mediaType.withoutParameters().toString());
} catch (IllegalArgumentException e) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown content-type: " + req.getContentType());
LOGGER.warn("Unknown content type in request", e);
return;
}
} else {
LOGGER.debug("Request is missing content type.");
}
Serializer responseSerializer = requestSerializer;
String acceptHeader = req.getHeader("Accept");
if (acceptHeader != null) {
String[] entries = acceptHeader.split("[,]");
for (String entry : entries) {
entry = entry.trim();
if (entry.isEmpty()) {
continue;
}
if ("*/*".equals(entry)) {
// Then responding same as request is good.
break;
}
try {
MediaType mediaType = MediaType.parse(entry);
responseSerializer = serializerProvider.getSerializer(mediaType.withoutParameters().toString());
break;
} catch (IllegalArgumentException ignore) {
// Ignore. Bad header input is pretty common.
}
}
}
MessageReader reader = new IOMessageReader(req.getInputStream(), requestSerializer);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
MessageWriter writer = new IOMessageWriter(baos, responseSerializer);
getHandler(processor).process(reader, writer);
resp.setStatus(HttpServletResponse.SC_OK);
if (baos.size() > 0) {
resp.setContentType(responseSerializer.mediaType());
resp.setContentLength(baos.size());
resp.getOutputStream().write(baos.toByteArray());
resp.getOutputStream().flush();
}
long endTime = System.nanoTime();
double duration = ((double) (endTime - startTime)) / NS_IN_MILLIS;
try {
instrumentation.onComplete(duration, callRef.get(), responseRef.get());
} catch (Throwable th) {
LOGGER.error("Exception in service instrumentation", th);
}
} catch (EOFException e) {
// output stream closed before write is complete.
// So we cannot even try to respond.
long endTime = System.nanoTime();
double duration = ((double) (endTime - startTime)) / NS_IN_MILLIS;
try {
instrumentation.onTransportException(e, duration, callRef.get(), responseRef.get());
} catch (Throwable th) {
LOGGER.error("Exception in service instrumentation", th);
}
} catch (Exception e) {
try {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal server error: " + e.getMessage());
} catch (IOException ioEx) {
e.addSuppressed(ioEx);
}
long endTime = System.nanoTime();
double duration = ((double) (endTime - startTime)) / NS_IN_MILLIS;
try {
instrumentation.onTransportException(e, duration, callRef.get(), responseRef.get());
} catch (Throwable th) {
LOGGER.error("Exception in service instrumentation", th);
}
}
}
Aggregations