private Function<ServiceMessage, Object> msgToResp() { return sm -> sm.hasData() ? sm.data() : UNEXPECTED_EMPTY_RESPONSE; }
private Function<ServiceMessage, Object> msgToResp() { return sm -> sm.hasData() ? sm.data() : UNEXPECTED_EMPTY_RESPONSE; }
private Payload generatePayload(ServiceMessage msg) { try { ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); dataCodec.encode(dataStream, msg.data()); System.out.println("generated dataBuffer: " + dataStream.toString()); ByteBuf dataBuffer = ByteBufAllocator.DEFAULT.buffer(); dataBuffer.writeBytes(dataStream.toByteArray()); ByteArrayOutputStream headersStream = new ByteArrayOutputStream(); headersCodec.encode(headersStream, msg.headers()); System.out.println("generated headersBuffer: " + headersStream.toString()); ByteBuf headersBuffer = ByteBufAllocator.DEFAULT.buffer(); headersBuffer.writeBytes(headersStream.toByteArray()); return ByteBufPayload.create(dataBuffer, headersBuffer); } catch (Throwable t) { throw new RuntimeException(t.getMessage(), t); } }
private Mono<Void> error(HttpServerResponse httpResponse, ServiceMessage response) { int code = response.errorType(); HttpResponseStatus status = HttpResponseStatus.valueOf(code); ByteBuf content = response.hasData(ErrorData.class) ? encodeData(response.data(), response.dataFormatOrDefault()) : response.data(); return httpResponse.status(status).sendObject(content).then(); }
private Mono<Address> addressLookup(ServiceMessage request) { Callable<Address> callable = () -> router .route(serviceRegistry, request) .map(ServiceReference::address) .orElseThrow(() -> noReachableMemberException(request)); return Mono.fromCallable(callable) .doOnError( t -> { Optional<Object> dataOptional = Optional.ofNullable(request.data()); dataOptional.ifPresent(ReferenceCountUtil::safestRelease); }); }
private Mono<Void> error(HttpServerResponse httpResponse, ServiceMessage response) { int code = Integer.parseInt(Qualifier.getQualifierAction(response.qualifier())); HttpResponseStatus status = HttpResponseStatus.valueOf(code); ByteBuf content = response.hasData(ErrorData.class) ? encodeData(response.data(), response.dataFormatOrDefault()) : response.data(); return httpResponse.status(status).sendObject(content).then(); }
private Mono<Address> addressLookup(ServiceMessage request) { Callable<Address> callable = () -> router .route(serviceRegistry, request) .map(ServiceReference::address) .orElseThrow(() -> noReachableMemberException(request)); return Mono.fromCallable(callable) .doOnError( t -> { Optional<Object> dataOptional = Optional.ofNullable(request.data()); dataOptional.ifPresent(ReferenceCountUtil::safestRelease); }); }
/** * 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(); } }
private Object toRequest( ServiceMessage message, BiFunction<ServiceMessage, Class<?>, ServiceMessage> dataDecoder) { ServiceMessage request = dataDecoder.apply(message, methodInfo.requestType()); if (!methodInfo.isRequestTypeVoid() && !methodInfo.isRequestTypeServiceMessage() && !request.hasData(methodInfo.requestType())) { Optional<?> dataOptional = Optional.ofNullable(request.data()); Class<?> clazz = dataOptional.map(Object::getClass).orElse(null); throw new BadRequestException( String.format( "Expected service request data of type: %s, but received: %s", methodInfo.requestType(), clazz)); } return methodInfo.isRequestTypeServiceMessage() ? request : request.data(); }
/** * Performs basic validation on incoming message: qualifier must be present, method invoker must * be present in the method registry by incoming qualifier. May throw exception * * @param message incoming message * @throws ServiceException in case qualfier is missing or method invoker is missing by given * qualifier */ private void validateRequest(ServiceMessage message) throws ServiceException { if (message.qualifier() == null) { Optional.ofNullable(message.data()) .ifPresent(ReferenceCountUtil::safestRelease); // release message data if any LOGGER.error("Failed to invoke service with msg={}: qualifier is null", message); throw new BadRequestException("Qualifier is null in service msg request: " + message); } if (!methodRegistry.containsInvoker(message.qualifier())) { Optional.ofNullable(message.data()) .ifPresent(ReferenceCountUtil::safestRelease); // release message data if any LOGGER.error( "Failed to invoke service with msg={}: no service invoker found by qualifier={}", message, message.qualifier()); throw new ServiceUnavailableException( "No service invoker found by qualifier=" + message.qualifier()); } } }
/** * Performs basic validation on incoming message: qualifier must be present, method invoker must * be present in the method registry by incoming qualifier. May throw exception * * @param message incoming message * @throws ServiceException in case qualfier is missing or method invoker is missing by given * qualifier */ private void validateRequest(ServiceMessage message) throws ServiceException { if (message.qualifier() == null) { Optional.ofNullable(message.data()) .ifPresent(ReferenceCountUtil::safestRelease); // release message data if any LOGGER.error("Failed to invoke service with msg={}: qualifier is null", message); throw new BadRequestException("Qualifier is null in service msg request: " + message); } if (!methodRegistry.containsInvoker(message.qualifier())) { Optional.ofNullable(message.data()) .ifPresent(ReferenceCountUtil::safestRelease); // release message data if any LOGGER.error( "Failed to invoke service with msg={}: no service invoker found by qualifier={}", message, message.qualifier()); throw new ServiceUnavailableException( "No service invoker found by qualifier=" + message.qualifier()); } } }
/** * Performs basic validation on incoming message: qualifier must be present, method invoker must * be present in the method registry by incoming qualifier. May throw exception * * @param message incoming message * @throws ServiceException in case qualfier is missing or method invoker is missing by given * qualifier */ private void validateRequest(ServiceMessage message) throws ServiceException { if (message.qualifier() == null) { Optional.ofNullable(message.data()) .ifPresent(ReferenceCountUtil::safestRelease); // release message data if any LOGGER.error("Failed to invoke service with msg={}: qualifier is null", message); throw new BadRequestException("Qualifier is null in service msg request: " + message); } if (!methodRegistry.containsInvoker(message.qualifier())) { Optional.ofNullable(message.data()) .ifPresent(ReferenceCountUtil::safestRelease); // release message data if any LOGGER.error( "Failed to invoke service with msg={}: no service invoker found by qualifier={}", message, message.qualifier()); throw new ServiceUnavailableException( "No service invoker found by qualifier=" + message.qualifier()); } } }
@Override public Throwable toError(ServiceMessage message) { ErrorData data = message.data(); if (data.getErrorCode() == 42) { // implement service mapping logic return new ServiceAException(data.getErrorMessage()); } else { // or delegate it to default mapper return DefaultErrorMapper.INSTANCE.toError(message); } } }
/** * 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()); }
/** * Get a builder by pattern form given {@link ServiceMessage}. * * @param message ServiceMessage form where to copy field values. * @return builder with fields copied from given {@link ServiceMessage} */ public static Builder from(ServiceMessage message) { return new Builder().headers(message.headers()).data(message.data()); }
ByteBuf headersBuffer = state.headersBuffer().retain(); ServiceMessage message = messageCodec.decode(dataBuffer, headersBuffer); ReferenceCountUtil.release(message.data()); timeContext.stop(); meter.mark();
/** * 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 -> { LatencyHelper latencyHelper = new LatencyHelper(state); BenchmarkMeter clientToServiceMeter = state.meter("meter.client-to-service"); BenchmarkMeter serviceToClientMeter = state.meter("meter.service-to-client"); ServiceCall serviceCall = state.serviceCall(); return i -> { clientToServiceMeter.mark(); return serviceCall .requestOne(enrichRequest()) .map(RequestOneBenchmark::enrichResponse) .doOnNext( message -> { serviceToClientMeter.mark(); Optional.ofNullable(message.data()) .ifPresent(ReferenceCountUtil::safestRelease); latencyHelper.calculate(message); }) .doOnError(ex -> LOGGER.warn("Exception occured: " + ex)); }; }); }
@Override public Throwable toError(ServiceMessage message) { ErrorData data = message.data(); int errorType = message.errorType(); int errorCode = data.getErrorCode(); String errorMessage = data.getErrorMessage(); switch (errorType) { case BadRequestException.ERROR_TYPE: return new BadRequestException(errorCode, errorMessage); case UnauthorizedException.ERROR_TYPE: return new UnauthorizedException(errorCode, errorMessage); case ServiceUnavailableException.ERROR_TYPE: return new ServiceUnavailableException(errorCode, errorMessage); case InternalServiceException.ERROR_TYPE: return new InternalServiceException(errorCode, errorMessage); // Handle other types of Service Exceptions here default: return new InternalServiceException(errorCode, errorMessage); } }