/** * 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.agent; import static org.junit.Assert.assertEquals; import java.io.IOException; import java.util.List; import java.util.Map; import org.apache.avro.ipc.AvroRemoteException; import org.apache.avro.ipc.HttpServer; import org.apache.avro.ipc.Server; import org.apache.avro.specific.SpecificResponder; import org.apache.thrift.transport.TTransportException; import org.junit.Test; import org.mortbay.log.Log; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.cloudera.flume.conf.FlumeConfigData; import com.cloudera.flume.conf.FlumeConfiguration; import com.cloudera.flume.conf.avro.AvroFlumeConfigData; import com.cloudera.flume.reporter.server.avro.AvroFlumeReport; import com.cloudera.flume.conf.avro.AvroFlumeClientServer; import com.cloudera.flume.conf.avro.FlumeNodeState; import com.cloudera.flume.master.MasterClientServerAvro; public class TestAvroMultiMasterRPC { static final Logger LOG = LoggerFactory.getLogger(TestAvroMultiMasterRPC.class); /** * Mock AvroServer. */ public class MockAvroServer implements AvroFlumeClientServer { boolean first = true; protected Server server; public void stop() { this.server.close(); } public MockAvroServer() { } public void serve(int port) throws IOException { LOG .info(String .format( "Starting blocking thread pool server for control server on port %d...", port)); SpecificResponder res = new SpecificResponder( AvroFlumeClientServer.class, this); this.server = new HttpServer(res, port); this.server.start(); } @Override public java.lang.Void acknowledge(CharSequence ackid) throws AvroRemoteException { return null; } @Override public boolean checkAck(CharSequence ackid) throws AvroRemoteException { Log.info("Check-ack called at server on " + this.server.getPort()); if (first) { first = false; return true; } Log.info("throwing an exception on " + this.server.getPort()); throw new RuntimeException("Throwing an exception"); } @Override public AvroFlumeConfigData getConfig(CharSequence sourceId) throws AvroRemoteException { return MasterClientServerAvro.configToAvro(new FlumeConfigData()); } @Override public List<CharSequence> getLogicalNodes(CharSequence physNode) throws AvroRemoteException { return null; } @Override public boolean heartbeat(CharSequence logicalNode, CharSequence physicalNode, CharSequence clienthost, FlumeNodeState s, long timestamp) throws AvroRemoteException { return true; } @Override public Void putReports(Map<CharSequence, AvroFlumeReport> reports) throws AvroRemoteException { return null; } @Override public Map<CharSequence, Integer> getChokeMap(CharSequence physNode) throws AvroRemoteException { return null; } } /** * Tries to connect to several servers in turn and compensate as masters fail. */ @Test public void testConnect() throws TTransportException, IOException, InterruptedException { FlumeConfiguration conf = FlumeConfiguration.get(); conf.set(FlumeConfiguration.MASTER_HEARTBEAT_SERVERS, "localhost:9999,localhost:56789,localhost:56790"); conf.set(FlumeConfiguration.MASTER_HEARBEAT_RPC, "AVRO"); MultiMasterRPC masterRPC = new MultiMasterRPC(conf, false); MockAvroServer server1 = new MockAvroServer(); server1.serve(56789); MockAvroServer server2 = new MockAvroServer(); server2.serve(56790); assertEquals(true, masterRPC.checkAck("UNKNOWNACK")); // Server should roll // over to 56789 assertEquals("Port should have been 56789, got " + masterRPC.getCurPort(), 56789, masterRPC.getCurPort()); masterRPC.checkAck("UNKNOWNACK"); // should cause exception, fail // over to 56790 assertEquals("Port should have been 56790, got " + masterRPC.getCurPort(), 56790, masterRPC.getCurPort()); masterRPC.close(); server2.stop(); } }