// Copyright 2016 Twitter. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.twitter.heron.integration_test.common.bolt; import java.io.IOException; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.twitter.heron.api.bolt.BaseBasicBolt; import com.twitter.heron.api.bolt.BasicOutputCollector; import com.twitter.heron.api.topology.OutputFieldsDeclarer; import com.twitter.heron.api.tuple.Fields; import com.twitter.heron.api.tuple.Tuple; import com.twitter.heron.api.tuple.Values; /** * A bolt that read a tweet in json format, and then filter out the top-level property given and * emit it. * Example, given the property "id", this bolt will read a tweet and emit the value of key "id" in * top level of the tweet's json. */ public class TweetPropertyBolt extends BaseBasicBolt { private static final long serialVersionUID = -3049021294446207050L; private static final Logger LOG = Logger.getLogger(TweetPropertyBolt.class.getName()); private static final ObjectMapper MAPPER = new ObjectMapper(); private String propName; public TweetPropertyBolt(String propName) { this.propName = propName; } @Override public void execute(Tuple tuple, BasicOutputCollector basicOutputCollector) { Object prop = extract(tuple.getString(0), propName); if (prop != null) { basicOutputCollector.emit(new Values(prop)); } } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields(propName)); } /** * Extract the prop used from a tweet in json type */ private Object extract(String tweet, String prop) { // Parse JSON entry Map<String, Object> tweetJson = null; try { tweetJson = MAPPER.readValue(tweet, new TypeReference<Map<String, Object>>() { }); } catch (IOException e) { LOG.log(Level.SEVERE, "Failed to parse the String into map: " + tweet, e); } Object property = null; if (tweetJson == null) { property = ""; } else { // Is this a tweet if (tweetJson.containsKey("id") && tweetJson.containsKey("created_at") && tweetJson.containsKey("text") && tweetJson.containsKey("user")) { property = tweetJson.get(prop); } } return property; } }