/** * Create a RESTPubSub from a {@link BulletConfig}. * * @param config The config. * @throws PubSubException if the context name is not present or cannot be parsed. */ public RESTPubSub(BulletConfig config) throws PubSubException { super(config); this.config = new RESTPubSubConfig(config); }
@Override public List<Subscriber> getSubscribers(int n) { return IntStream.range(0, n).mapToObj(i -> getSubscriber()).collect(Collectors.toList()); } }
@Override public List<Publisher> getPublishers(int n) { return IntStream.range(0, n).mapToObj(i -> getPublisher()).collect(Collectors.toList()); }
@Override public Publisher getPublisher() { int connectTimeout = config.getAs(RESTPubSubConfig.PUBLISHER_CONNECT_TIMEOUT, Integer.class); if (context == Context.QUERY_PROCESSING) { return new RESTResultPublisher(HttpClients.createDefault(), connectTimeout); } else { String queryURL = ((List<String>) config.getAs(RESTPubSubConfig.QUERY_URLS, List.class)).get(0); String resultURL = config.getAs(RESTPubSubConfig.RESULT_URL, String.class); return new RESTQueryPublisher(HttpClients.createDefault(), queryURL, resultURL, connectTimeout); } }
/** * Constructor that loads the defaults and augments it with defaults. * * @param other The other config to wrap. */ public RESTPubSubConfig(Config other) { super(DEFAULT_REST_PUBSUB_CONFIGURATION_NAME); merge(other); VALIDATOR.validate(this); log.info("Merged settings:\n {}", this); }
@Override public void send(PubSubMessage message) { String url = (String) message.getMetadata().getContent(); log.debug("Extracted url to which to send results: {}", url); sendToURL(url, message); } }
/** * Send the {@link PubSubMessage} to the given url. * * @param url The url to which to send the message. * @param message The message to send. */ protected void sendToURL(String url, PubSubMessage message) { log.debug("Sending message: {} to url: {}", message, url); try (CloseableHttpResponse response = client.execute(makeHttpPost(url, message))) { if (response == null || response.getStatusLine().getStatusCode() != RESTPubSub.OK_200) { log.error("Couldn't POST to REST pubsub server. Got response: {}", response); } } catch (Exception e) { log.error("Error when trying to POST. Message was: {}. Error was: ", message.asJSON(), e); } }
@Override public void send(PubSubMessage message) { // Put responseURL in the metadata so the ResponsePublisher knows to which host to send the response Metadata metadata = message.getMetadata(); metadata = metadata == null ? new Metadata() : metadata; metadata.setContent(resultURL); message.setMetadata(metadata); sendToURL(queryURL, message); } }
@Override public Subscriber getSubscriber() { int maxUncommittedMessages = config.getAs(RESTPubSubConfig.MAX_UNCOMMITTED_MESSAGES, Integer.class); int connectTimeout = config.getAs(RESTPubSubConfig.SUBSCRIBER_CONNECT_TIMEOUT, Integer.class); List<String> urls; Long minWait; if (context == Context.QUERY_PROCESSING) { urls = (List<String>) config.getAs(RESTPubSubConfig.QUERY_URLS, List.class); minWait = config.getAs(RESTPubSubConfig.QUERY_SUBSCRIBER_MIN_WAIT, Long.class); } else { urls = Collections.singletonList(config.getAs(RESTPubSubConfig.RESULT_URL, String.class)); minWait = config.getAs(RESTPubSubConfig.RESULT_SUBSCRIBER_MIN_WAIT, Long.class); } return new RESTSubscriber(maxUncommittedMessages, urls, HttpClients.createDefault(), minWait, connectTimeout); }
@Override public List<PubSubMessage> getMessages() { List<PubSubMessage> messages = new ArrayList<>(); long currentTime = System.currentTimeMillis(); if (currentTime - lastRequest <= minWait) { return messages; } lastRequest = currentTime; for (String url : urls) { try (CloseableHttpResponse response = client.execute(makeHttpGet(url))) { int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == RESTPubSub.OK_200) { HttpEntity httpEntity = response.getEntity(); String message = EntityUtils.toString(httpEntity, RESTPubSub.UTF_8); log.debug("Received message from url: {}. Message was {}", url, message); messages.add(PubSubMessage.fromJSON(message)); EntityUtils.consume(httpEntity); } else if (statusCode != RESTPubSub.NO_CONTENT_204) { // NO_CONTENT_204 indicates there are no new messages - anything else indicates a problem log.error("HTTP call to {} failed with status code {} and response {}.", url, statusCode, response); } } catch (Exception e) { log.error("HTTP call to {} failed with error:", url, e); } } return messages; }