/** * Describes whether the message is an error. * * @return <code>true</code> if error, otherwise <code>false</code>. */ public boolean isError() { String qualifier = qualifier(); return qualifier != null && qualifier.contains(Qualifier.ERROR_NAMESPACE); }
private ServiceUnavailableException noReachableMemberException(ServiceMessage request) { LOGGER.error( "Failed to invoke service, " + "No reachable member with such service definition [{}], args [{}]", request.qualifier(), request); return new ServiceUnavailableException( "No reachable member with such service: " + request.qualifier()); }
private ServiceUnavailableException noReachableMemberException(ServiceMessage request) { LOGGER.error( "Failed to invoke service, " + "No reachable member with such service definition [{}], args [{}]", request.qualifier(), request); return new ServiceUnavailableException( "No reachable member with such service: " + request.qualifier()); }
@Override public Optional<ServiceReference> route(ServiceRegistry serviceRegistry, ServiceMessage request) { List<ServiceReference> serviceInstances = serviceRegistry.lookupService(request); if (serviceInstances.isEmpty()) { return Optional.empty(); } else if (serviceInstances.size() == 1) { return Optional.of(serviceInstances.get(0)); } else { AtomicInteger counter = counterByServiceName.computeIfAbsent(request.qualifier(), or -> new AtomicInteger()); int index = (counter.incrementAndGet() & Integer.MAX_VALUE) % serviceInstances.size(); return Optional.of(serviceInstances.get(index)); } } }
@Override public List<ServiceReference> lookupService(ServiceMessage request) { List<ServiceReference> result = referencesByQualifier.get(request.qualifier()); if (result == null || result.isEmpty()) { return Collections.emptyList(); } String contentType = request.dataFormatOrDefault(); return result .stream() .filter(ref -> ref.contentTypes().contains(contentType)) .collect(Collectors.toList()); }
@Override public List<ServiceReference> lookupService(ServiceMessage request) { List<ServiceReference> result = referencesByQualifier.get(request.qualifier()); if (result == null || result.isEmpty()) { return Collections.emptyList(); } String contentType = request.dataFormatOrDefault(); return result .stream() .filter(ref -> ref.contentTypes().contains(contentType)) .collect(Collectors.toList()); }
@Override public Optional<ServiceReference> route(ServiceRegistry serviceRegistry, ServiceMessage request) { List<ServiceReference> serviceInstances = serviceRegistry.lookupService(request); if (serviceInstances.isEmpty()) { return Optional.empty(); } else if (serviceInstances.size() == 1) { return Optional.of(serviceInstances.get(0)); } else { AtomicInteger counter = counterByServiceName.computeIfAbsent(request.qualifier(), or -> new AtomicInteger()); int index = (counter.incrementAndGet() & Integer.MAX_VALUE) % serviceInstances.size(); return Optional.of(serviceInstances.get(index)); } } }
/** * Returns error type. Error type is an identifier of a group of errors. * * @return error type. */ public int errorType() { if (!isError()) { throw new IllegalStateException("Message is not an error"); } try { return Integer.parseInt(Qualifier.getQualifierAction(qualifier())); } catch (NumberFormatException e) { throw new IllegalStateException("Error type must be a number"); } }
@Override public Mono<Payload> requestResponse(Payload payload) { return Mono.fromCallable(() -> toMessage(payload)) .doOnNext(this::validateRequest) .flatMap( message -> { ServiceMethodInvoker methodInvoker = methodRegistry.getInvoker(message.qualifier()); return methodInvoker.invokeOne(message, ServiceMessageCodec::decodeData); }) .map(this::toPayload); }
@Override public Mono<Payload> requestResponse(Payload payload) { return Mono.fromCallable(() -> toMessage(payload)) .doOnNext(this::validateRequest) .flatMap( message -> { ServiceMethodInvoker methodInvoker = methodRegistry.getInvoker(message.qualifier()); return methodInvoker.invokeOne(message, ServiceMessageCodec::decodeData); }) .map(this::toPayload); }
/** * Issues request-and-reply request. * * @param request request message to send. * @param responseType type of response. * @return mono publisher completing with single response message or with error. */ public Mono<ServiceMessage> requestOne(ServiceMessage request, Class<?> responseType) { return Mono.defer( () -> { String qualifier = request.qualifier(); if (methodRegistry.containsInvoker(qualifier)) { // local service. return methodRegistry .getInvoker(request.qualifier()) .invokeOne(request, ServiceMessageCodec::decodeData) .map(this::throwIfError); } else { return addressLookup(request) .flatMap(address -> requestOne(request, responseType, address)); // remote service } }); }
/** * Issues request-and-reply request. * * @param request request message to send. * @param responseType type of response. * @return mono publisher completing with single response message or with error. */ public Mono<ServiceMessage> requestOne(ServiceMessage request, Class<?> responseType) { return Mono.defer( () -> { String qualifier = request.qualifier(); if (methodRegistry.containsInvoker(qualifier)) { // local service. return methodRegistry .getInvoker(request.qualifier()) .invokeOne(request, ServiceMessageCodec::decodeData) .map(this::throwIfError); } else { return addressLookup(request) .flatMap(address -> requestOne(request, responseType, address)); // remote service } }); }
@Override public Mono<Payload> requestResponse(Payload payload) { return Mono.fromCallable(() -> toMessage(payload)) .doOnNext(this::validateRequest) .flatMap( message -> { ServiceMethodInvoker methodInvoker = methodRegistry.getInvoker(message.qualifier()); return methodInvoker.invokeOne(message, ServiceMessageCodec::decodeData); }) .onErrorResume(ex -> Mono.just(ExceptionProcessor.toMessage(ex))) .map(this::toPayload); }
@Override public Flux<Payload> requestStream(Payload payload) { return Mono.fromCallable(() -> toMessage(payload)) .doOnNext(this::validateRequest) .flatMapMany( message -> { ServiceMethodInvoker methodInvoker = methodRegistry.getInvoker(message.qualifier()); return methodInvoker.invokeMany(message, ServiceMessageCodec::decodeData); }) .map(this::toPayload); }
@Override public Flux<Payload> requestStream(Payload payload) { return Mono.fromCallable(() -> toMessage(payload)) .doOnNext(this::validateRequest) .flatMapMany( message -> { ServiceMethodInvoker methodInvoker = methodRegistry.getInvoker(message.qualifier()); return methodInvoker.invokeMany(message, ServiceMessageCodec::decodeData); }) .map(this::toPayload); }
@Override public Flux<Payload> requestStream(Payload payload) { return Mono.fromCallable(() -> toMessage(payload)) .doOnNext(this::validateRequest) .flatMapMany( message -> { ServiceMethodInvoker methodInvoker = methodRegistry.getInvoker(message.qualifier()); return methodInvoker.invokeMany(message, ServiceMessageCodec::decodeData); }) .onErrorResume(this::toMessage) .map(this::toPayload); }
@Override public Flux<Payload> requestChannel(Publisher<Payload> payloads) { return Flux.from(HeadAndTail.createFrom(Flux.from(payloads).map(this::toMessage))) .flatMap( pair -> { ServiceMessage message = pair.head(); validateRequest(message); Flux<ServiceMessage> messages = Flux.from(pair.tail()).startWith(message); ServiceMethodInvoker methodInvoker = methodRegistry.getInvoker(message.qualifier()); return methodInvoker.invokeBidirectional(messages, ServiceMessageCodec::decodeData); }) .map(this::toPayload); }
@Override public Flux<Payload> requestChannel(Publisher<Payload> payloads) { return Flux.from(HeadAndTail.createFrom(Flux.from(payloads).map(this::toMessage))) .flatMap( pair -> { ServiceMessage message = pair.head(); validateRequest(message); Flux<ServiceMessage> messages = Flux.from(pair.tail()).startWith(message); ServiceMethodInvoker methodInvoker = methodRegistry.getInvoker(message.qualifier()); return methodInvoker.invokeBidirectional(messages, ServiceMessageCodec::decodeData); }) .map(this::toPayload); }
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(); }
@Override public Flux<Payload> requestChannel(Publisher<Payload> payloads) { return Flux.from(HeadAndTail.createFrom(Flux.from(payloads).map(this::toMessage))) .flatMap( pair -> { ServiceMessage message = pair.head(); validateRequest(message); Flux<ServiceMessage> messages = Flux.from(pair.tail()).startWith(message); ServiceMethodInvoker methodInvoker = methodRegistry.getInvoker(message.qualifier()); return methodInvoker.invokeBidirectional(messages, ServiceMessageCodec::decodeData); }) .onErrorResume(this::toMessage) .map(this::toPayload); }