/** * Licensed to Cloudera, Inc. under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. Cloudera, Inc. licenses this file * to you 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.cloudera.flume.master; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.cloudera.flume.conf.FlumeConfiguration; import com.cloudera.flume.conf.thrift.ThriftFlumeClientServer; import com.cloudera.flume.conf.thrift.ThriftFlumeConfigData; import com.cloudera.flume.conf.FlumeConfigData; import com.cloudera.flume.conf.thrift.FlumeNodeState; import com.cloudera.flume.conf.thrift.ThriftFlumeClientServer.Iface; import com.cloudera.flume.master.StatusManager.NodeState; import com.cloudera.flume.reporter.ReportEvent; import com.cloudera.flume.reporter.server.thrift.ThriftFlumeReport; import com.cloudera.flume.util.ThriftServer; import com.google.common.base.Preconditions; /** * Thrift implementation of a Master server. Performs type conversion and * delegates to a MasterClientServer. */ public class MasterClientServerThrift extends ThriftServer implements ThriftFlumeClientServer.Iface, RPCServer { static final Logger LOG = LoggerFactory.getLogger(MasterClientServerThrift.class); final protected int port; protected MasterClientServer delegate; public MasterClientServerThrift(MasterClientServer delegate) { Preconditions.checkArgument(delegate != null, "MasterCleintServer is null in 'ThriftMasterClientServer!"); this.delegate = delegate; this.port = FlumeConfiguration.get().getMasterHeartbeatPort(); } public List<String> getLogicalNodes(String physNode) throws TException { return delegate.getLogicalNodes(physNode); } public Map<String, Integer> getChokeMap(String physNode) throws TException { return delegate.getChokeMap(physNode); } public ThriftFlumeConfigData getConfig(String host) throws TException { return configToThrift(delegate.getConfig(host)); } public boolean heartbeat(String logicalNode, String physicalNode, String clienthost, FlumeNodeState s, long version) throws TException { return delegate.heartbeat(logicalNode, physicalNode, clienthost, stateFromThrift(s), version); } public void acknowledge(String ackid) throws TException { delegate.acknowledge(ackid); } public boolean checkAck(String ackid) throws TException { return delegate.checkAck(ackid); } public void putReports(Map<String, ThriftFlumeReport> reports) throws TException { Preconditions.checkNotNull(reports, "putReports called with null report map"); Map<String, ReportEvent> reportsMap = new HashMap<String, ReportEvent>(); for (final Entry<String, ThriftFlumeReport> r : reports.entrySet()) { ReportEvent event = new ReportEvent(r.getValue().longMetrics, r .getValue().stringMetrics, r.getValue().doubleMetrics); reportsMap.put(r.getKey(), event); } delegate.putReports(reportsMap); } // CONTROL public void serve() throws IOException { LOG .info(String .format( "Starting blocking thread pool server for control server on port %d...", port)); try { this.start(new ThriftFlumeClientServer.Processor((Iface) this), port, "MasterClientServer"); } catch (TTransportException e) { throw new IOException(e.getMessage()); } } // TYPE CONVERSION /** * Converts a thrift generated NodeStatus enum value to a flume master * StatusManager NodeState enum */ public static NodeState stateFromThrift(FlumeNodeState s) { Preconditions.checkNotNull(s, "Argument may not be null."); switch (s) { case ACTIVE: return NodeState.ACTIVE; case CONFIGURING: return NodeState.CONFIGURING; case ERROR: return NodeState.ERROR; case HELLO: return NodeState.HELLO; case IDLE: return NodeState.IDLE; case LOST: return NodeState.LOST; case DECOMMISSIONED: return NodeState.DECOMMISSIONED; default: throw new IllegalStateException("Unknown value " + s); } } public static FlumeConfigData configFromThrift(ThriftFlumeConfigData in) { if (in == null) { return null; } FlumeConfigData out = new FlumeConfigData(); out.timestamp = in.timestamp; out.sourceConfig = in.sourceConfig; out.sinkConfig = in.sinkConfig; out.sourceVersion = in.sourceVersion; out.sinkVersion = in.sinkVersion; out.flowID = in.flowID; return out; } public static ThriftFlumeConfigData configToThrift(FlumeConfigData in) { if (in == null) { return null; } ThriftFlumeConfigData out = new ThriftFlumeConfigData(); out.timestamp = in.timestamp; out.sourceConfig = in.sourceConfig; out.sinkConfig = in.sinkConfig; out.sourceVersion = in.sourceVersion; out.sinkVersion = in.sinkVersion; out.flowID = in.flowID; return out; } /** * Converts a flume master StatusManager NodeState enum to a thrift generated * NodeStatus enum value. */ public static FlumeNodeState stateToThrift(NodeState s) { Preconditions.checkNotNull(s, "Argument may not be null."); switch (s) { case ACTIVE: return FlumeNodeState.ACTIVE; case CONFIGURING: return FlumeNodeState.CONFIGURING; case ERROR: return FlumeNodeState.ERROR; case HELLO: return FlumeNodeState.HELLO; case IDLE: return FlumeNodeState.IDLE; case LOST: return FlumeNodeState.LOST; case DECOMMISSIONED: return FlumeNodeState.DECOMMISSIONED; default: throw new IllegalStateException("Unknown value " + s); } } }