/* * #! * % * Copyright (C) 2014 - 2016 Humboldt-Universität zu Berlin * % * 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 storm.lrb; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import storm.lrb.bolt.AccountBalanceBolt; import storm.lrb.bolt.DailyExpenditureBolt; import storm.lrb.tools.Helper; import storm.lrb.tools.StopWatch; import backtype.storm.Config; import backtype.storm.generated.StormTopology; import backtype.storm.topology.IRichSpout; import backtype.storm.topology.TopologyBuilder; import backtype.storm.tuple.Fields; import de.hub.cs.dbis.aeolus.sinks.FileSinkBolt; import de.hub.cs.dbis.lrb.operators.AccidentDetectionBolt; import de.hub.cs.dbis.lrb.operators.AccidentNotificationBolt; import de.hub.cs.dbis.lrb.operators.AverageVehicleSpeedBolt; import de.hub.cs.dbis.lrb.operators.DispatcherBolt; import de.hub.cs.dbis.lrb.operators.LatestAverageVelocityBolt; import de.hub.cs.dbis.lrb.operators.TollNotificationBolt; import de.hub.cs.dbis.lrb.queries.utils.TopologyControl; import de.hub.cs.dbis.lrb.toll.MemoryTollDataStore; /** * An encapsulation of parameters which allows fast switches of the spout. Does everything essential for the cluster and * allow to manipulate {@link Config} and {@link StormTopology} at will after creation in constructor. * * @author richter * @author mjsax */ public class LRBTopology { private final static Logger LOGGER = LoggerFactory.getLogger(LRBTopology.class); private final StormTopology stormTopology; private final String tollDataStoreClass = MemoryTollDataStore.class.getName(); /** * performs the assembly of the topology which can be retrieved with {@link #getStormTopology() }. * * @param nameext * @param xways * @param workers * @param tasks * @param executors * @param offset * @param spout * @param stormTimer * @param local * @param histFile * @param topologyNamePrefix * @param stormConfig * an existing {@link Config} object to be filled with serialization and custom bolt information */ public LRBTopology(String nameext, int xways, int workers, int tasks, int executors, int offset, IRichSpout spout, StopWatch stormTimer, boolean local, String histFile, String topologyNamePrefix, Config stormConfig) { List<String> fields = new LinkedList<String>(Arrays.asList(TopologyControl.XWAY_FIELD_NAME, TopologyControl.DIRECTION_FIELD_NAME)); TopologyBuilder builder = new TopologyBuilder(); builder.setSpout(TopologyControl.SPOUT_NAME, spout, 1); builder.setBolt(TopologyControl.SPLIT_STREAM_BOLT_NAME, new DispatcherBolt(), 2 * xways).setNumTasks(4 * xways) .shuffleGrouping(TopologyControl.SPOUT_NAME);// .allGrouping("Spout", // "stormtimer"); builder.setBolt(TopologyControl.AVERAGE_SPEED_BOLT_NAME, new AverageVehicleSpeedBolt(), xways * 3) .fieldsGrouping( TopologyControl.SPLIT_STREAM_BOLT_NAME, TopologyControl.POSITION_REPORTS_STREAM_ID, new Fields(TopologyControl.XWAY_FIELD_NAME, TopologyControl.SEGMENT_FIELD_NAME, TopologyControl.DIRECTION_FIELD_NAME)); builder.setBolt(TopologyControl.LATEST_AVERAGE_SPEED_BOLT_NAME, new LatestAverageVelocityBolt(), xways * 3) .fieldsGrouping( TopologyControl.AVERAGE_SPEED_BOLT_NAME, TopologyControlOld.LAST_AVERAGE_SPEED_STREAM_ID, new Fields(TopologyControl.XWAY_FIELD_NAME, TopologyControl.SEGMENT_FIELD_NAME, TopologyControl.DIRECTION_FIELD_NAME)); builder.setBolt(TopologyControl.TOLL_ASSESSMENTS_FILE_WRITER_BOLT_NAME, new FileSinkBolt(topologyNamePrefix + "_toll"), 1).allGrouping(TopologyControl.TOLL_NOTIFICATION_BOLT_NAME, TopologyControl.TOLL_ASSESSMENTS_STREAM_ID); // builder.setBolt("lavBolt", new SegmentStatsBolt(0), cmd.xways*3) // .fieldsGrouping("SplitStreamBolt", "PosReports", new Fields("xsd")); builder .setBolt(TopologyControl.TOLL_NOTIFICATION_BOLT_NAME, new TollNotificationBolt(), executors) .setNumTasks(tasks) .fieldsGrouping(TopologyControl.LATEST_AVERAGE_SPEED_BOLT_NAME, TopologyControlOld.LAST_AVERAGE_SPEED_STREAM_ID, new Fields(fields)) .fieldsGrouping( TopologyControl.ACCIDENT_DETECTION_BOLT_NAME, TopologyControlOld.ACCIDENT_INFO_STREAM_ID, new Fields(TopologyControlOld.POS_REPORT_FIELD_NAME, TopologyControl.SEGMENT_FIELD_NAME, TopologyControlOld.ACCIDENT_INFO_FIELD_NAME)) .fieldsGrouping(TopologyControl.SPLIT_STREAM_BOLT_NAME, TopologyControl.POSITION_REPORTS_STREAM_ID, new Fields(fields)); builder.setBolt(TopologyControl.ACCIDENT_DETECTION_BOLT_NAME, new AccidentDetectionBolt(), xways) .fieldsGrouping(TopologyControl.SPLIT_STREAM_BOLT_NAME, TopologyControl.POSITION_REPORTS_STREAM_ID, new Fields(TopologyControl.XWAY_FIELD_NAME, TopologyControl.DIRECTION_FIELD_NAME)); builder.setBolt(TopologyControl.ACCIDENT_NOTIFICATION_BOLT_NAME, new AccidentNotificationBolt(), xways) .fieldsGrouping(TopologyControl.ACCIDENT_DETECTION_BOLT_NAME, TopologyControlOld.ACCIDENT_INFO_STREAM_ID, // streamId new Fields(TopologyControlOld.POS_REPORT_FIELD_NAME)) .fieldsGrouping(TopologyControl.SPLIT_STREAM_BOLT_NAME, TopologyControl.POSITION_REPORTS_STREAM_ID, // streamId new Fields(TopologyControl.XWAY_FIELD_NAME, TopologyControl.DIRECTION_FIELD_NAME)); builder.setBolt(TopologyControl.ACCIDENT_FILE_WRITER_BOLT_NAME, new FileSinkBolt(topologyNamePrefix + "_acc"), 1).allGrouping(TopologyControl.ACCIDENT_DETECTION_BOLT_NAME, TopologyControlOld.ACCIDENT_INFO_STREAM_ID); builder .setBolt(TopologyControlOld.ACCOUNT_BALANCE_BOLT_NAME, new AccountBalanceBolt(), xways) .fieldsGrouping(TopologyControl.SPLIT_STREAM_BOLT_NAME, TopologyControl.ACCOUNT_BALANCE_REQUESTS_STREAM_ID, new Fields(TopologyControl.VEHICLE_ID_FIELD_NAME)) .fieldsGrouping(TopologyControl.TOLL_NOTIFICATION_BOLT_NAME, TopologyControl.TOLL_ASSESSMENTS_STREAM_ID, new Fields(TopologyControlOld.ACCOUNT_BALANCE_REQUEST_FIELD_NAME)); builder.setBolt(TopologyControlOld.ACCOUNT_BALANCE_FILE_WRITER_BOLT_NAME, new FileSinkBolt(topologyNamePrefix + "_bal"), 1).allGrouping(TopologyControlOld.ACCOUNT_BALANCE_BOLT_NAME); builder.setBolt(TopologyControlOld.DAILY_EXPEDITURE_BOLT_NAME, new DailyExpenditureBolt(), xways * 1) .shuffleGrouping(TopologyControl.SPLIT_STREAM_BOLT_NAME, TopologyControl.DAILY_EXPEDITURE_REQUESTS_STREAM_ID); builder.setBolt(TopologyControlOld.DAILY_EXPEDITURE_FILE_WRITER_BOLT_NAME, new FileSinkBolt(topologyNamePrefix + "_exp"), 1) .allGrouping(TopologyControlOld.DAILY_EXPEDITURE_BOLT_NAME); stormConfig.registerSerialization(de.hub.cs.dbis.lrb.types.PositionReport.class); stormConfig.registerSerialization(de.hub.cs.dbis.lrb.types.AccountBalanceRequest.class); stormConfig.registerSerialization(de.hub.cs.dbis.lrb.types.DailyExpenditureRequest.class); stormConfig.registerSerialization(de.hub.cs.dbis.lrb.types.TravelTimeRequest.class); stormConfig.registerSerialization(storm.lrb.model.Accident.class); stormConfig.registerSerialization(storm.lrb.model.VehicleInfo.class); stormConfig.registerSerialization(storm.lrb.tools.StopWatch.class); stormConfig.registerSerialization(storm.lrb.model.AccidentImmutable.class); stormConfig.put(Helper.TOLL_DATA_STORE_CONF_KEY, this.tollDataStoreClass); this.stormTopology = builder.createTopology(); LOGGER.info(String.format("successfully created storm topology '%s'", TopologyControl.TOPOLOGY_NAME)); } public StormTopology getStormTopology() { return this.stormTopology; } }