/** * Constructor for a message having content, a {@link Signal} and a sequence number. * * @param id The ID associated with the message. * @param content The content of the message. * @param signal The Signal to be sent with the message. * @param sequence The sequence number of the message. */ public PubSubMessage(String id, String content, Signal signal, int sequence) { this(id, content, new Metadata(signal, null), sequence); }
private Metadata withSignal(Metadata metadata, Metadata.Signal signal) { // Don't change the non-readonly bits of metadata in place since that might affect tuples emitted but pending. Metadata copy = new Metadata(signal, null); if (metadata != null) { copy.setContent(metadata.getContent()); } return copy; }
private static boolean isSameMetadata(Object actual, Object expected) { Metadata actualMetadata = (Metadata) actual; Metadata expectedMetadata = (Metadata) expected; if (actualMetadata.getSignal() != expectedMetadata.getSignal()) { return false; } Serializable actualContent = actualMetadata.getContent(); Serializable expectedContent = expectedMetadata.getContent(); return actualContent == expectedContent || actualContent.equals(expectedContent); }
@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 void send(PubSubMessage message) throws PubSubException { Metadata metadata = message.getMetadata(); // Remove the content String content = metadata.getContent().toString(); log.debug("Removing metadata {} for result {}@{}: {}", content, message.getId(), message.getSequence(), message.getContent()); metadata.setContent(null); String serializedMessage = message.asJSON(); Tuple tuple = new DRPCTuple(new Values(serializedMessage, content)); // This sends the message through DRPC and not to the collector but it acks or fails accordingly. bolt.execute(tuple); if (!collector.isAcked()) { throw new PubSubException("Message not acked. Unable to send message through DRPC:\n " + serializedMessage); } // Otherwise, we're good to proceed collector.reset(); }
@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); } }
@Override public void execute(Tuple tuple) { String id = tuple.getString(TopologyConstants.ID_POSITION); Metadata metadata = (Metadata) tuple.getValue(TopologyConstants.METADATA_POSITION); log.info("Looping back metadata with signal {} for {}", metadata.getSignal(), id); publish(new PubSubMessage(id, null, metadata), tuple); } }
/** * Check if Metadata has the given signal. * * @param signal The signal to check against. * @return true if message has {@link Metadata#signal} */ public boolean hasSignal(Signal signal) { return hasSignal() && this.signal == signal; } }
@Override public void send(PubSubMessage message) throws PubSubException { Metadata metadata = message.getMetadata(); // Remove the content String content = metadata.getContent().toString(); log.debug("Removing metadata {} for result {}@{}: {}", content, message.getId(), message.getSequence(), message.getContent()); metadata.setContent(null); String serializedMessage = message.asJSON(); Tuple tuple = new DRPCTuple(new Values(serializedMessage, content)); // This sends the message through DRPC and not to the collector but it acks or fails accordingly. bolt.execute(tuple); if (!collector.isAcked()) { throw new PubSubException("Message not acked. Unable to send message through DRPC:\n " + serializedMessage); } // Otherwise, we're good to proceed collector.reset(); }
Assert.assertTrue(actual.hasMetadata()); Metadata metadata = actual.getMetadata(); Assert.assertEquals(metadata.getContent(), makeReturnInfo("fakefoo", "testHost", 0)); Assert.assertTrue(actual.hasMetadata()); metadata = actual.getMetadata(); Assert.assertEquals(metadata.getContent(), makeReturnInfo("fakefoo", "testHost", 1)); Assert.assertTrue(actual.hasMetadata()); metadata = actual.getMetadata(); Assert.assertEquals(metadata.getContent(), makeReturnInfo("fakebar", "testHost", 2));
@Override public void execute(Tuple tuple) { String id = tuple.getString(TopologyConstants.ID_POSITION); Metadata metadata = (Metadata) tuple.getValue(TopologyConstants.METADATA_POSITION); log.info("Looping back metadata with signal {} for {}", metadata.getSignal(), id); publish(new PubSubMessage(id, null, metadata), tuple); } }
/** * Check if the message has a {@link Signal}. * * @return true if message has a signal. */ public boolean hasSignal() { return hasMetadata() && metadata.hasSignal(); }
private void emitMetaSignal(String id, Metadata.Signal signal) { log.error("Emitting {} signal to the feedback stream for {}", signal, id); collector.emit(FEEDBACK_STREAM, new Values(id, new Metadata(signal, null))); }
private Metadata withSignal(Metadata metadata, Metadata.Signal signal) { // Don't change the non-readonly bits of metadata in place since that might affect tuples emitted but pending. Metadata copy = new Metadata(signal, null); if (metadata != null) { copy.setContent(metadata.getContent()); } return copy; }
/** * Handles a metadata message for a query. * * @param tuple The metadata tuple. * @return The created {@link Metadata}. */ protected Metadata onMeta(Tuple tuple) { String id = tuple.getString(TopologyConstants.ID_POSITION); Metadata metadata = (Metadata) tuple.getValue(TopologyConstants.METADATA_POSITION); if (metadata == null) { return null; } Metadata.Signal signal = metadata.getSignal(); if (signal == Metadata.Signal.KILL || signal == Metadata.Signal.COMPLETE) { removeQuery(id); log.info("Received {} signal and killed query: {}", signal, id); } return metadata; }
/** * Check if message has a given {@link Signal}. * * @param signal The signal to check for. * @return true if message has the given signal. */ public boolean hasSignal(Signal signal) { return hasMetadata() && metadata.hasSignal(signal); }
private void emitMetaSignal(String id, Metadata.Signal signal) { log.error("Emitting {} signal to the feedback stream for {}", signal, id); collector.emit(FEEDBACK_STREAM, new Values(id, new Metadata(signal, null))); }
/** * Handles a metadata message for a query. * * @param tuple The metadata tuple. * @return The created {@link Metadata}. */ protected Metadata onMeta(Tuple tuple) { String id = tuple.getString(TopologyConstants.ID_POSITION); Metadata metadata = (Metadata) tuple.getValue(TopologyConstants.METADATA_POSITION); if (metadata == null) { return null; } Metadata.Signal signal = metadata.getSignal(); if (signal == Metadata.Signal.KILL || signal == Metadata.Signal.COMPLETE) { removeQuery(id); log.info("Received {} signal and killed query: {}", signal, id); } return metadata; }
@Override public List<PubSubMessage> getMessages() throws PubSubException { // Try and read from DRPC. The DRPCSpout does a sleep for 1 ms if there are no tuples, so we don't have to do it. spout.nextTuple(); if (!collector.haveOutput()) { return null; } // The DRPCSpout only should have emitted one tuple List<List<Object>> tuples = collector.reset(); log.debug("Have a message through DRPC {}", tuples); List<Object> tupleAndID = tuples.get(0); // The first object is the actual DRPCSpout tuple and the second is the DRPC messageID. List<Object> tuple = (List<Object>) tupleAndID.get(0); Object drpcID = tupleAndID.get(1); // The first object in the tuple is our PubSubMessage as JSON String pubSubMessageJSON = (String) tuple.get(0); // The second object in the tuple is the serialized returnInfo added by the DRPCSpout String returnInfo = (String) tuple.get(1); log.debug("Read message\n{}\nfrom DRPC with return information {}", pubSubMessageJSON, returnInfo); PubSubMessage pubSubMessage = PubSubMessage.fromJSON(pubSubMessageJSON); // Add returnInfo as metadata. Cannot add it to pubSubMessage String id = pubSubMessage.getId(); String content = pubSubMessage.getContent(); int sequence = pubSubMessage.getSequence(); PubSubMessage message = new PubSubMessage(id, content, new Metadata(null, returnInfo), sequence); emittedIDs.put(ImmutablePair.of(id, sequence), drpcID); return Collections.singletonList(message); }
@Override public List<PubSubMessage> getMessages() throws PubSubException { // Try and read from DRPC. The DRPCSpout does a sleep for 1 ms if there are no tuples, so we don't have to do it. spout.nextTuple(); if (!collector.haveOutput()) { return null; } // The DRPCSpout only should have emitted one tuple List<List<Object>> tuples = collector.reset(); log.debug("Have a message through DRPC {}", tuples); List<Object> tupleAndID = tuples.get(0); // The first object is the actual DRPCSpout tuple and the second is the DRPC messageID. List<Object> tuple = (List<Object>) tupleAndID.get(0); Object drpcID = tupleAndID.get(1); // The first object in the tuple is our PubSubMessage as JSON String pubSubMessageJSON = (String) tuple.get(0); // The second object in the tuple is the serialized returnInfo added by the DRPCSpout String returnInfo = (String) tuple.get(1); log.debug("Read message\n{}\nfrom DRPC with return information {}", pubSubMessageJSON, returnInfo); PubSubMessage pubSubMessage = PubSubMessage.fromJSON(pubSubMessageJSON); // Add returnInfo as metadata. Cannot add it to pubSubMessage String id = pubSubMessage.getId(); String content = pubSubMessage.getContent(); int sequence = pubSubMessage.getSequence(); PubSubMessage message = new PubSubMessage(id, content, new Metadata(null, returnInfo), sequence); emittedIDs.put(ImmutablePair.of(id, sequence), drpcID); return Collections.singletonList(message); }