public static SmileEnvelopeEvent fromPOJO(final String eventName, final Granularity granularity, final DateTime eventDateTime, final Object pojo) { JsonNode tree = smileObjectMapper.valueToTree(pojo); return new SmileEnvelopeEvent(eventName, granularity, eventDateTime, tree); }
private void setEventPropertiesFromNode(final JsonNode node) { if (eventDateTime == null) { eventDateTime = getEventDateTimeFromJson(node); } if (granularity == null) { granularity = getGranularityFromJson(node); } }
@Override public byte[] getSerializedEvent() { if (serializedEvent == null) { // can we not avoid serializing it if we already have bytes? try { serializedEvent = getObjectMapper().writeValueAsBytes(root); } catch (IOException e) { // would rather this was thrown, but signature won't allow it: return null; } } return serializedEvent; }
@Override public void trackRequest(final RequestLog request) { try { controller.offerEvent(SmileEnvelopeEvent.fromPOJO(eventName, Granularity.HOURLY, new DateTime(DateTimeZone.UTC), request)); } catch (IOException e) { log.warn("Got I/O exception trying to send RequestLog [{}]: {}", request, e.toString()); } } }
public SmileEnvelopeEvent(final String eventName, final Granularity granularity, final DateTime eventDateTime, final Map<String, Object> map) throws IOException { this.eventName = eventName; this.eventDateTime = eventDateTime; this.granularity = granularity; ObjectNode root = getObjectMapper().createObjectNode(); root.put(SMILE_EVENT_DATETIME_TOKEN_NAME, eventDateTime.getMillis()); root.put(SMILE_EVENT_GRANULARITY_TOKEN_NAME, granularity.toString()); for (Map.Entry<String, Object> entry : map.entrySet()) { addToTree(root, entry.getKey(), entry.getValue()); } this.root = root; }
/** * The object implements the readExternal method to restore its * contents by calling the methods of DataInput for primitive * types and readObject for objects, strings and arrays. The * readExternal method must read the values in the same sequence * and with the same types as were written by writeExternal. * * @param in the stream to read data from in order to restore the object * @throws java.io.IOException if I/O errors occur */ @Override public void readExternal(final ObjectInput in) throws IOException { // Name of the event first final int smileEventNameBytesSize = in.readInt(); final byte[] eventNameBytes = new byte[smileEventNameBytesSize]; in.readFully(eventNameBytes); eventName = new String(eventNameBytes, NAME_CHARSET); // Then payload final int smilePayloadSize = in.readInt(); final byte[] smilePayload = new byte[smilePayloadSize]; in.readFully(smilePayload); root = parseAsTree(smilePayload); setEventPropertiesFromNode(root); }
protected SmileEnvelopeEvent(final String eventName, final Granularity granularity, final DateTime eventDateTime, final JsonNode node) { this.eventName = eventName; this.granularity = granularity; this.eventDateTime = eventDateTime; this.root = node; setEventPropertiesFromNode(node); }
public SmileEnvelopeEvent(final String eventName, final byte[] inputBytes, final DateTime eventDateTime, final Granularity granularity) throws IOException { this.eventName = eventName; this.serializedEvent = inputBytes; this.eventDateTime = eventDateTime; this.granularity = granularity; this.root = parseAsTree(inputBytes); }
/** * The object implements the writeExternal method to save its contents * by calling the methods of DataOutput for its primitive values or * calling the writeObject method of ObjectOutput for objects, strings, * and arrays. * * @param out the stream to write the object to * @throws java.io.IOException Includes any I/O exceptions that may occur * @serialData Overriding methods should use this tag to describe * the data layout of this Externalizable object. * List the sequence of element types and, if possible, * relate the element to a public/protected field and/or * method of this Externalizable class. */ @Override public void writeExternal(final ObjectOutput out) throws IOException { // Name of the event final byte[] eventNameBytes = eventName.getBytes(NAME_CHARSET); out.writeInt(eventNameBytes.length); out.write(eventNameBytes); final byte[] payloadBytes = getSerializedEvent(); // Size of Smile payload. Needed for deserialization, see below out.writeInt(payloadBytes.length); out.write(payloadBytes); }
/** * Extracts the next event in the stream. * Note: Stream must be formatted as an array of (serialized) SmileEnvelopeEvents. * * @return nextEvent. return null if it reaches the end of the list * @throws IOException if there's a parsing issue */ public SmileEnvelopeEvent getNextEvent() throws IOException { try { if (!_hasNextEvent()) { return null; } final JsonNode node = mapper.readValue(parser, JsonNode.class); nextToken = null; // reset nextToken return new SmileEnvelopeEvent(node); } // make sure we don't return true for hasNextEvent after this catch (IOException e) { hasFailed = true; throw e; } }
@Override public String getOutputDir(final String prefix) { final GranularityPathMapper pathMapper = new GranularityPathMapper(String.format("%s/%s", prefix, eventName), granularity); return pathMapper.getPathForDateTime(getEventDateTime()); }
@SuppressWarnings("deprecation") public SmileEnvelopeEvent(final JsonNode node) throws IOException { eventName = node.path("eventName").asText(); root = node.get("payload"); if ((root == null || root.size() == 0) || (eventName == null || eventName.isEmpty())) { throw new IOException("Cannot construct a SmileEnvelopeEvent from just a JsonNode unless JsonNode has eventName and payload properties."); } setEventPropertiesFromNode(root); }
private JsonNode parseAsTree(final byte[] smilePayload) throws IOException { return getObjectMapper().readTree(new ByteArrayInputStream(smilePayload)); }
public void writeToJsonGenerator(final JsonGenerator gen) throws IOException { // writes '{eventName:<name>,payload:{<data>}}' --it's kind of silly but ultimately inconsequential to nest them like this. gen.writeStartObject(); gen.writeStringField("eventName", eventName); gen.writeFieldName("payload"); /* Note: output format used depends completely on generator we are being passed * and NOT on which mapper we use -- mappers are format independent and rely * on underlying JsonParser/JsonGenerator for low-level handling. */ getObjectMapper().writeTree(gen, root); gen.writeEndObject(); }