/** * Decode buffers. * * @param dataBuffer the buffer of the data (payload) * @param headersBuffer the buffer of the headers * @return a new Service message with {@link ByteBuf} data and with parsed headers. * @throws MessageCodecException when decode fails */ public ServiceMessage decode(ByteBuf dataBuffer, ByteBuf headersBuffer) throws MessageCodecException { ServiceMessage.Builder builder = ServiceMessage.builder(); if (dataBuffer.isReadable()) { builder.data(dataBuffer); } if (headersBuffer.isReadable()) { try (ByteBufInputStream stream = new ByteBufInputStream(headersBuffer, true)) { builder.headers(headersCodec.decode(stream)); } catch (Throwable ex) { ReferenceCountUtil.safestRelease(dataBuffer); // release data buf as well throw new MessageCodecException("Failed to decode message headers", ex); } } return builder.build(); }
/** * Decode message. * * @param message the original message (with {@link ByteBuf} data) * @param dataType the type of the data. * @return a new Service message that upon {@link ServiceMessage#data()} returns the actual data * (of type data type) * @throws MessageCodecException when decode fails */ public static ServiceMessage decodeData(ServiceMessage message, Class<?> dataType) throws MessageCodecException { if (!message.hasData(ByteBuf.class) || dataType == null) { return message; } Object data; Class<?> targetType = message.isError() ? ErrorData.class : dataType; ByteBuf dataBuffer = message.data(); try (ByteBufInputStream inputStream = new ByteBufInputStream(dataBuffer, true)) { DataCodec dataCodec = DataCodec.getInstance(message.dataFormatOrDefault()); data = dataCodec.decode(inputStream, targetType); } catch (Throwable ex) { throw new MessageCodecException( "Failed to decode data on message q=" + message.qualifier(), ex); } return ServiceMessage.from(message).data(data).build(); } }
/** * Main method. * * @param args - params of main method. */ public static void main(String[] args) { BenchmarkSettings settings = BenchmarkSettings.from(args).build(); new BenchmarkServiceState(settings, new BenchmarkServiceImpl()) .runForAsync( state -> { BenchmarkService benchmarkService = state.service(BenchmarkService.class); BenchmarkTimer timer = state.timer("timer"); BenchmarkMeter meter = state.meter("meter"); ServiceMessage message = ServiceMessage.builder().qualifier(QUALIFIER).build(); return i -> { Context timeContext = timer.time(); return benchmarkService .requestVoid(message) .doOnTerminate(timeContext::stop) .doOnTerminate(meter::mark); }; }); } }
private Mono<Void> handleRequest( ByteBuf content, HttpServerRequest httpRequest, HttpServerResponse httpResponse) { String qualifier = httpRequest.uri(); Builder builder = ServiceMessage.builder().qualifier(qualifier).data(content); enrichRequest(httpRequest.requestHeaders(), builder); return serviceCall .requestOne(builder.build()) .doOnNext(message -> metrics.markServiceResponse()) .switchIfEmpty( Mono.defer(() -> Mono.just(ServiceMessage.builder().qualifier(qualifier).build()))) .flatMap( response -> { enrichResponse(httpResponse, response); return Mono.defer( () -> ExceptionProcessor.isError(response) // check error ? error(httpResponse, response) : response.hasData() // check data ? ok(httpResponse, response) : noContent(httpResponse)); }); }
private Mono<Void> handleRequest( ByteBuf content, HttpServerRequest httpRequest, HttpServerResponse httpResponse) { String qualifier = httpRequest.uri(); Builder builder = ServiceMessage.builder().qualifier(qualifier).data(content); enrichRequest(httpRequest.requestHeaders(), builder); return serviceCall .requestOne(builder.build()) .doOnNext(message -> metrics.markServiceResponse()) .switchIfEmpty( Mono.defer(() -> Mono.just(ServiceMessage.builder().qualifier(qualifier).build()))) .flatMap( response -> { enrichResponse(httpResponse, response); return Mono.defer( () -> response.isError() // check error ? error(httpResponse, response) : response.hasData() // check data ? ok(httpResponse, response) : noContent(httpResponse)); }); }
/** * Instantiates new message with error qualifier for given error type and specified error code and * message. * * @param errorType the error type to be used in message qualifier. * @param errorCode the error code. * @param errorMessage the error message. * @return builder. */ public static ServiceMessage error(int errorType, int errorCode, String errorMessage) { return ServiceMessage.builder() .qualifier(Qualifier.asError(errorType)) .data(new ErrorData(errorCode, errorMessage)) .build(); }
public Builder qualifier(String qualifier) { return header(HEADER_QUALIFIER, qualifier); }
public Builder qualifier(String serviceName, String methodName) { return qualifier(Qualifier.asString(serviceName, methodName)); }
@Override public Mono<ServiceMessage> one(ServiceMessage message) { Callable<ServiceMessage> callable = () -> { long value = System.currentTimeMillis(); return ServiceMessage.from(message) .header(SERVICE_RECV_TIME, value) .header(SERVICE_SEND_TIME, value) .data("hello") .build(); }; return Mono.fromCallable(callable); }
@Override public Mono<ServiceMessage> one(ServiceMessage message) { Callable<ServiceMessage> callable = () -> { long value = System.currentTimeMillis(); return ServiceMessage.from(message) .header(SERVICE_RECV_TIME, value) .header(SERVICE_SEND_TIME, value) .data("hello") .build(); }; return Mono.fromCallable(callable); }
private void enrichRequest(HttpHeaders requestHeaders, Builder builder) { Optional.ofNullable(requestHeaders.get(CLIENT_SEND_TIME)) .ifPresent(value -> builder.header(CLIENT_SEND_TIME, value)); Optional.ofNullable(requestHeaders.get(CLIENT_RECV_TIME)) .ifPresent(value -> builder.header(CLIENT_RECV_TIME, value)); Optional.ofNullable(requestHeaders.get(SERVICE_RECV_TIME)) .ifPresent(value -> builder.header(SERVICE_RECV_TIME, value)); Optional.ofNullable(requestHeaders.get(SERVICE_SEND_TIME)) .ifPresent(value -> builder.header(SERVICE_SEND_TIME, value)); }
private void enrichRequest(HttpHeaders requestHeaders, Builder builder) { Optional.ofNullable(requestHeaders.get(CLIENT_SEND_TIME)) .ifPresent(value -> builder.header(CLIENT_SEND_TIME, value)); Optional.ofNullable(requestHeaders.get(CLIENT_RECV_TIME)) .ifPresent(value -> builder.header(CLIENT_RECV_TIME, value)); Optional.ofNullable(requestHeaders.get(SERVICE_RECV_TIME)) .ifPresent(value -> builder.header(SERVICE_RECV_TIME, value)); Optional.ofNullable(requestHeaders.get(SERVICE_SEND_TIME)) .ifPresent(value -> builder.header(SERVICE_SEND_TIME, value)); }
/** * Instantiates new message with the same data and headers as at given message. * * @param message the message to be copied * @return a new message, with the same data and headers */ public static Builder from(ServiceMessage message) { return ServiceMessage.builder().data(message.data()).headers(message.headers()); }
private ServiceMessage toServiceMessage(MethodInfo methodInfo, Object... params) { if (methodInfo.parameterCount() != 0 && params[0] instanceof ServiceMessage) { return ServiceMessage.from((ServiceMessage) params[0]) .qualifier(methodInfo.serviceName(), methodInfo.methodName()) .build(); } return ServiceMessage.builder() .qualifier(methodInfo.serviceName(), methodInfo.methodName()) .data(methodInfo.parameterCount() != 0 ? params[0] : null) .build(); }