@Override public <T> Optional<T> getConnectionEndpoint(Class<T> protocol) { return member.getConnectionEndpoint(protocol); }
@Override public boolean local() { return member.local(); }
@Override public String toString() { return member.name() + "(" + segmentCount + ")"; } }
private Optional<MessageRoutingInformation> requestMessageRoutingInformation(ServiceInstance serviceInstance) { Member member = buildMember(serviceInstance); if (member.local()) { return Optional.of(getLocalMessageRoutingInformation()); } URI endpoint = member.getConnectionEndpoint(URI.class) .orElseThrow(() -> new IllegalArgumentException(String.format( "No Connection Endpoint found in Member [%s] for protocol [%s] to send a " + "%s request to", member, URI.class, MessageRoutingInformation.class.getSimpleName() ))); URI destinationUri = buildURIForPath(endpoint, messageRoutingInformationEndpoint); try { ResponseEntity<MessageRoutingInformation> responseEntity = restTemplate.exchange(destinationUri, HttpMethod.GET, HttpEntity.EMPTY, MessageRoutingInformation.class); return Optional.ofNullable(responseEntity.getBody()); } catch (HttpClientErrorException e) { logger.info("Blacklisting Service [" + serviceInstance.getServiceId() + "], " + "as requesting message routing information from it resulted in an exception.", logger.isDebugEnabled() ? e : null); return Optional.empty(); } catch (Exception e) { logger.info("Failed to receive message routing information from Service [" + serviceInstance.getServiceId() + "] due to an exception. " + "Will temporarily set this instance to deny all incoming messages", logger.isDebugEnabled()?e:null); return Optional.of(unreachableService); } }
@Override public void suspect() { member.suspect(); }
@Override public <C> void dispatch(CommandMessage<C> command) { LoggingCallback loggingCallback = LoggingCallback.INSTANCE; if (NoOpMessageMonitor.INSTANCE.equals(messageMonitor)) { CommandMessage<? extends C> interceptedCommand = intercept(command); Optional<Member> optionalDestination = commandRouter.findDestination(interceptedCommand); if (optionalDestination.isPresent()) { Member destination = optionalDestination.get(); try { connector.send(destination, interceptedCommand); } catch (Exception e) { destination.suspect(); loggingCallback.onResult(interceptedCommand, asCommandResultMessage( new CommandDispatchException(DISPATCH_ERROR_MESSAGE + ": " + e.getMessage(), e) )); } } else { loggingCallback.onResult(interceptedCommand, asCommandResultMessage(new NoHandlerForCommandException( format("No node known to accept [%s]", interceptedCommand.getCommandName()) ))); } } else { dispatch(command, loggingCallback); } }
@Override public <T> Optional<T> getConnectionEndpoint(Class<T> protocol) { return member.getConnectionEndpoint(protocol); }
@Override public String name() { return member.name(); }
@Override public boolean local() { return member.local(); }
} catch (Exception e) { messageMonitorCallback.reportFailure(e); destination.suspect(); callback.onResult(interceptedCommand, asCommandResultMessage( new CommandDispatchException(DISPATCH_ERROR_MESSAGE + ": " + e.getMessage(), e)
@Override public <T> Optional<T> getConnectionEndpoint(Class<T> protocol) { return member.getConnectionEndpoint(protocol); }
/** * Deregisters the given {@code member} and returns a new {@link ConsistentHash} with updated memberships. * * @param member the member to remove from the consistent hash * @return a new {@link ConsistentHash} instance with updated memberships */ public ConsistentHash without(Member member) { Assert.notNull(member, () -> "Member may not be null"); if (!members.containsKey(member.name())) { return this; } Map<String, ConsistentHashMember> newMembers = new TreeMap<>(members); newMembers.remove(member.name()); return new ConsistentHash(newMembers, hashFunction, modCount + 1); }
@Override public boolean local() { return member.local(); }
@Override public void suspect() { member.suspect(); }
/** * Resolve the JGroups Address of the given {@code Member}. * * @param destination The node of which to solve the Address * @return The JGroups Address of the given node * * @throws CommandBusConnectorCommunicationException when an error occurs resolving the adress */ protected Address resolveAddress(Member destination) { return destination.getConnectionEndpoint(Address.class).orElseThrow( () -> new CommandBusConnectorCommunicationException( "The target member doesn't expose a JGroups endpoint")); }
/** * Registers the given {@code member} with given {@code loadFactor} and {@code commandFilter} if it is not * already contained in the {@link ConsistentHash}. It will return the current ConsistentHash if the addition is * a duplicate and returns a new ConsistentHash with updated memberships if it is not. * <p> * The relative loadFactor of the member determines the likelihood of being selected as a destination for a command. * * @param member the member to register * @param loadFactor the load factor of the new member * @param commandFilter filter describing which commands can be handled by the given member * @return a new {@link ConsistentHash} instance with updated memberships */ public ConsistentHash with(Member member, int loadFactor, CommandMessageFilter commandFilter) { Assert.notNull(member, () -> "Member may not be null"); ConsistentHashMember newMember = new ConsistentHashMember(member, loadFactor, commandFilter); if (members.containsKey(member.name()) && newMember.equals(members.get(member.name()))) { return this; } Map<String, ConsistentHashMember> newMembers = new TreeMap<>(members); newMembers.put(member.name(), newMember); return new ConsistentHash(newMembers, hashFunction, modCount + 1); }
@Override public <C> void send(Member destination, CommandMessage<? extends C> commandMessage) { if (destination.local()) { localCommandBus.dispatch(commandMessage); } else { executor.execute(() -> { sendRemotely(destination, commandMessage, DO_NOT_EXPECT_REPLY); }); } }
@Override public void suspect() { member.suspect(); }
/** * Resolve the JGroups Address of the given {@code Member}. * * @param destination The node of which to solve the Address * @return The JGroups Address of the given node * * @throws CommandBusConnectorCommunicationException when an error occurs resolving the adress */ protected Address resolveAddress(Member destination) { return destination.getConnectionEndpoint(Address.class) .orElseThrow(() -> new CommandBusConnectorCommunicationException( "The target member doesn't expose a JGroups endpoint" )); }
@Override public String toString() { return member.name() + "(" + segmentCount + ")"; } }