@Override protected CompletionStage<Map<String, AddressMetric>> getSourceConnectionStatus(final Source source) { return collectAsList(IntStream.range(0, source.getConsumerCount()) .mapToObj(idx -> { final String topics = String.join(",", source.getAddresses()); final String actorLabel = MqttConsumerActor.ACTOR_NAME_PREFIX + getUniqueSourceSuffix(source.getIndex(), idx); final ActorRef consumer = consumerByActorNameWithIndex.get(actorLabel); return retrieveAddressMetric(topics, actorLabel, consumer); })) .thenApply(entries -> entries.stream().collect(Collectors.toMap(Pair::first, Pair::second))); }
@Override public AuthorizationContext getAuthorizationContext() { return delegate.getAuthorizationContext(); }
@Override public Optional<Enforcement> getEnforcement() { return delegate.getEnforcement(); }
@Override protected CompletionStage<Map<String, AddressMetric>> getSourceConnectionStatus(final Source source) { return collectAsList(source.getAddresses().stream() .flatMap(address -> IntStream.range(0, source.getConsumerCount()) .mapToObj(idx -> { final String addressWithIndex = address + "-" + idx; final String actorLabel = CONSUMER_ACTOR_PREFIX + addressWithIndex; final ActorRef consumer = consumerByAddressWithIndex.get(addressWithIndex); return retrieveAddressMetric(addressWithIndex, actorLabel, consumer); }) )) .thenApply(entries -> entries.stream().collect(Collectors.toMap(Pair::first, Pair::second))); }
private void startConsumers(final Channel channel) { final Optional<ActorRef> messageMappingProcessor = getMessageMappingProcessorActor(); if (messageMappingProcessor.isPresent()) { getSourcesOrEmptySet().forEach(source -> source.getAddresses().forEach(sourceAddress -> { for (int i = 0; i < source.getConsumerCount(); i++) { final String addressWithIndex = sourceAddress + "-" + i; final AuthorizationContext authorizationContext = source.getAuthorizationContext(); final Enforcement enforcement = source.getEnforcement().orElse(null); final HeaderMapping headerMapping = source.getHeaderMapping().orElse(null); final ActorRef consumer = startChildActorConflictFree( CONSUMER_ACTOR_PREFIX + addressWithIndex, RabbitMQConsumerActor.props(sourceAddress, messageMappingProcessor.get(), authorizationContext, enforcement, headerMapping)); consumerByAddressWithIndex.put(addressWithIndex, consumer); try { final String consumerTag = channel.basicConsume(sourceAddress, false, new RabbitMQMessageConsumer(consumer, channel)); log.debug("Consuming queue <{}>, consumer tag is <{}>.", addressWithIndex, consumerTag); consumedTagsToAddresses.put(consumerTag, addressWithIndex); } catch (final IOException e) { log.warning("Failed to consume queue <{}>: <{}>", addressWithIndex, e.getMessage()); } } }) ); } else { log.warning("The MessageMappingProcessor was not available and therefore no consumers were started!"); } }
final boolean dryRun) { if (source.getConsumerCount() <= 0) { log.info("source #{} has {} consumer - not starting stream", source.getIndex(), source.getConsumerCount()); return; (org.eclipse.ditto.model.connectivity.MqttSource) source; for (int i = 0; i < source.getConsumerCount(); i++) { log.debug("Starting {}. consumer actor for source <{}> on connection <{}>.", i, source.getIndex(), factory.connectionId()); final String uniqueSuffix = getUniqueSourceSuffix(source.getIndex(), i); final String actorNamePrefix = MqttConsumerActor.ACTOR_NAME_PREFIX + uniqueSuffix; MqttConsumerActor.props(messageMappingProcessorActor, source.getAuthorizationContext(), source.getEnforcement().orElse(null), dryRun); final ActorRef mqttConsumerActor = startChildActorConflictFree(actorNamePrefix, mqttConsumerActorProps); pendingStatusReportsFromStreams.add(firstConsumer); subscriptionInitialized.handle((done, error) -> { final Collection<String> sourceAddresses = source.getAddresses(); if (error == null) { log.info("Subscriptions {} initialized successfully", sourceAddresses);
private AmqpConsumerActor(final String sourceAddress, final MessageConsumer messageConsumer, final ActorRef messageMappingProcessor, final Source source) { this.sourceAddress = checkNotNull(sourceAddress, "sourceAddress"); this.messageConsumer = checkNotNull(messageConsumer); this.messageMappingProcessor = checkNotNull(messageMappingProcessor, "messageMappingProcessor"); checkNotNull(source, "source"); authorizationContext = source.getAuthorizationContext(); final Enforcement enforcement = source.getEnforcement().orElse(null); headerMapping = source.getHeaderMapping().orElse(null); addressMetric = ConnectivityModelFactory.newAddressMetric(ConnectionStatus.OPEN, "Started at " + Instant.now(), 0, null); headerEnforcementFilterFactory = enforcement != null ? EnforcementFactoryFactory.newEnforcementFilterFactory(enforcement, PlaceholderFactory.newHeadersPlaceholder()) : input -> null; }
@Override protected void validateSource(final Source source, final DittoHeaders dittoHeaders, final Supplier<String> sourceDescription) { source.getEnforcement().ifPresent(enforcement -> { validateTemplate(enforcement.getInput(), PlaceholderFactory.newHeadersPlaceholder(), dittoHeaders); enforcement.getFilters().forEach(filterTemplate -> validateTemplate(filterTemplate, PlaceholderFactory.newThingPlaceholder(), dittoHeaders)); }); source.getHeaderMapping().ifPresent(mapping -> validateHeaderMapping(mapping, dittoHeaders)); }
/** * Returns all non hidden marked fields of this {@code Source}. * * @return a JSON object representation of this Source including only non hidden marked fields. */ @Override default JsonObject toJson() { return toJson(FieldType.notHidden()); }
private void validateSourceAndTargetAddressesAreNonempty(final Connection connection, final DittoHeaders dittoHeaders) { connection.getSources().forEach(source -> { if (source.getAddresses().isEmpty() || source.getAddresses().contains("")) { final String location = String.format("Source %d of connection <%s>", source.getIndex(), connection.getId()); throw emptyAddressesError(location, dittoHeaders); } }); connection.getTargets().forEach(target -> { if (target.getAddress().isEmpty()) { final String location = String.format("Targets of connection <%s>", connection.getId()); throw emptyAddressesError(location, dittoHeaders); } target.getTopics().forEach(topic -> topic.getFilter().ifPresent(filter -> { // will throw an InvalidRqlExpressionException if the RQL expression was not valid: queryFilterCriteriaFactory.filterCriteria(filter, dittoHeaders); })); }); }
/** * If no context is set on connection level each target and source must have its own context. */ private void checkAuthorizationContextsAreValid() { // if the auth context on connection level is empty, // an auth context is required to be set on each source/target final Set<String> sourcesWithoutAuthContext = sources.stream() .filter(source -> source.getAuthorizationContext().isEmpty()) .flatMap(source -> source.getAddresses().stream()) .collect(Collectors.toSet()); final Set<String> targetsWithoutAuthContext = targets.stream() .filter(target -> target.getAuthorizationContext().isEmpty()) .map(Target::getAddress) .collect(Collectors.toSet()); if (!sourcesWithoutAuthContext.isEmpty() || !targetsWithoutAuthContext.isEmpty()) { final StringBuilder message = new StringBuilder("The "); if (!sourcesWithoutAuthContext.isEmpty()) { message.append("Sources ").append(sourcesWithoutAuthContext); } if (!sourcesWithoutAuthContext.isEmpty() && !targetsWithoutAuthContext.isEmpty()) { message.append(" and "); } if (!targetsWithoutAuthContext.isEmpty()) { message.append("Targets ").append(targetsWithoutAuthContext); } message.append(" are missing an authorization context."); throw ConnectionConfigurationInvalidException.newBuilder(message.toString()).build(); } }
@Override public int getIndex() { return delegate.getIndex(); }
@Override public Set<String> getAddresses() { return delegate.getAddresses(); }
@Override public Optional<HeaderMapping> getHeaderMapping() { return delegate.getHeaderMapping(); }
@Override public int getConsumerCount() { return delegate.getConsumerCount(); }
private void startConsumers(final Channel channel) { final Optional<ActorRef> messageMappingProcessor = getMessageMappingProcessorActor(); if (messageMappingProcessor.isPresent()) { getSourcesOrEmptySet().forEach(source -> source.getAddresses().forEach(sourceAddress -> { for (int i = 0; i < source.getConsumerCount(); i++) { final String addressWithIndex = sourceAddress + "-" + i; final AuthorizationContext authorizationContext = source.getAuthorizationContext(); final Enforcement enforcement = source.getEnforcement().orElse(null); final HeaderMapping headerMapping = source.getHeaderMapping().orElse(null); final ActorRef consumer = startChildActorConflictFree( CONSUMER_ACTOR_PREFIX + addressWithIndex, RabbitMQConsumerActor.props(sourceAddress, messageMappingProcessor.get(), authorizationContext, enforcement, headerMapping)); consumerByAddressWithIndex.put(addressWithIndex, consumer); try { final String consumerTag = channel.basicConsume(sourceAddress, false, new RabbitMQMessageConsumer(consumer, channel)); log.debug("Consuming queue <{}>, consumer tag is <{}>.", addressWithIndex, consumerTag); consumedTagsToAddresses.put(consumerTag, addressWithIndex); } catch (final IOException e) { log.warning("Failed to consume queue <{}>: <{}>", addressWithIndex, e.getMessage()); } } }) ); } else { log.warning("The MessageMappingProcessor was not available and therefore no consumers were started!"); } }
final boolean dryRun) { if (source.getConsumerCount() <= 0) { log.info("source #{} has {} consumer - not starting stream", source.getIndex(), source.getConsumerCount()); return; (org.eclipse.ditto.model.connectivity.MqttSource) source; for (int i = 0; i < source.getConsumerCount(); i++) { log.debug("Starting {}. consumer actor for source <{}> on connection <{}>.", i, source.getIndex(), factory.connectionId()); final String uniqueSuffix = getUniqueSourceSuffix(source.getIndex(), i); final String actorNamePrefix = MqttConsumerActor.ACTOR_NAME_PREFIX + uniqueSuffix; MqttConsumerActor.props(messageMappingProcessorActor, source.getAuthorizationContext(), source.getEnforcement().orElse(null), dryRun); final ActorRef mqttConsumerActor = startChildActorConflictFree(actorNamePrefix, mqttConsumerActorProps); pendingStatusReportsFromStreams.add(firstConsumer); subscriptionInitialized.handle((done, error) -> { final Collection<String> sourceAddresses = source.getAddresses(); if (error == null) { log.info("Subscriptions {} initialized successfully", sourceAddresses);
private AmqpConsumerActor(final String sourceAddress, final MessageConsumer messageConsumer, final ActorRef messageMappingProcessor, final Source source) { this.sourceAddress = checkNotNull(sourceAddress, "sourceAddress"); this.messageConsumer = checkNotNull(messageConsumer); this.messageMappingProcessor = checkNotNull(messageMappingProcessor, "messageMappingProcessor"); checkNotNull(source, "source"); authorizationContext = source.getAuthorizationContext(); final Enforcement enforcement = source.getEnforcement().orElse(null); headerMapping = source.getHeaderMapping().orElse(null); addressMetric = ConnectivityModelFactory.newAddressMetric(ConnectionStatus.OPEN, "Started at " + Instant.now(), 0, null); headerEnforcementFilterFactory = enforcement != null ? EnforcementFactoryFactory.newEnforcementFilterFactory(enforcement, PlaceholderFactory.newHeadersPlaceholder()) : input -> null; }
@Override protected void validateSource(final Source source, final DittoHeaders dittoHeaders, final Supplier<String> sourceDescription) { source.getEnforcement().ifPresent(enforcement -> { validateTemplate(enforcement.getInput(), PlaceholderFactory.newHeadersPlaceholder(), dittoHeaders); enforcement.getFilters().forEach(filterTemplate -> validateTemplate(filterTemplate, PlaceholderFactory.newThingPlaceholder(), dittoHeaders)); }); source.getHeaderMapping().ifPresent(mapping -> validateHeaderMapping(mapping, dittoHeaders)); }
@Override protected CompletionStage<Map<String, AddressMetric>> getSourceConnectionStatus(final Source source) { return collectAsList(source.getAddresses().stream() .flatMap(address -> IntStream.range(0, source.getConsumerCount()) .mapToObj(idx -> { final String addressWithIndex = address + "-" + idx; final String actorLabel = CONSUMER_ACTOR_PREFIX + addressWithIndex; final ActorRef consumer = consumerByAddressWithIndex.get(addressWithIndex); return retrieveAddressMetric(addressWithIndex, actorLabel, consumer); }) )) .thenApply(entries -> entries.stream().collect(Collectors.toMap(Pair::first, Pair::second))); }