docs: public void sendNotification(final String requestHost, final String topic) {
          // FIXME assert should not be used for validation because it can be disabled
          assert validTopics.isEmpty() || validTopics.contains(topic) : "That topic is not supported by this hub. " + topic;
          LOG.debug("Sending notification for {}", topic);
          try {
              final List<? extends Subscriber> subscribers = dao.subscribersForTopic(topic);
  
              if (subscribers.isEmpty()) {
                  LOG.debug("No subscribers to notify for {}", topic);
                  return;
              }
  
              final List<? extends SubscriptionSummary> summaries = dao.summariesForTopic(topic);
              int total = 0;
              final StringBuilder hosts = new StringBuilder();
  
              for (final SubscriptionSummary s : summaries) {
                  if (s.getSubscribers() > 0) {
                      total += s.getSubscribers();
                      hosts.append(" (").append(s.getHost()).append("; ").append(s.getSubscribers()).append(" subscribers)");
                  }
              }
  
              final StringBuilder userAgent = new StringBuilder("ROME-Certiorem (+http://").append(requestHost).append("; ").append(total)
                      .append(" subscribers)").append(hosts);
              final SyndFeed feed = fetcher.retrieveFeed(userAgent.toString(), new URL(topic));
              LOG.debug("Got feed for {}  Sending to {} subscribers.", topic, subscribers.size());
              notifier.notifySubscribers(subscribers, feed, new SubscriptionSummaryCallback() {
                  @Override
                  public void onSummaryInfo(final SubscriptionSummary summary) {
                      dao.handleSummary(topic, summary);
                  }
              });
          } catch (final Exception ex) {
              LOG.debug("Exception getting " + topic, ex);
              throw new HttpStatusCodeException(500, ex.getMessage(), ex);
          }
      }