Repository: incubator-htrace Updated Branches: refs/heads/master af5f174ff -> ad47b1a39
HTRACE-13 Fix htrace-hbase circular dependencies Change SpanReceiverFactory to be a builder. Project: http://git-wip-us.apache.org/repos/asf/incubator-htrace/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-htrace/commit/ad47b1a3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-htrace/tree/ad47b1a3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-htrace/diff/ad47b1a3 Branch: refs/heads/master Commit: ad47b1a39ab6f40d0c21d62b53558686fa60f88b Parents: af5f174 Author: stack <[email protected]> Authored: Thu Dec 11 13:41:46 2014 -0800 Committer: stack <[email protected]> Committed: Thu Dec 11 13:41:46 2014 -0800 ---------------------------------------------------------------------- .../org/apache/htrace/SpanReceiverBuilder.java | 117 ++++++++++++++++++ .../org/apache/htrace/SpanReceiverFactory.java | 95 -------------- .../apache/htrace/TestSpanReceiverBuilder.java | 122 ++++++++++++++++++ .../apache/htrace/TestSpanReceiverFactory.java | 123 ------------------- .../apache/htrace/HBaseHTraceConfiguration.java | 52 ++++++++ .../apache/htrace/HBaseSpanReceiverHost.java | 105 ++++++++++++++++ .../apache/htrace/impl/HBaseSpanReceiver.java | 92 +++++++------- .../org/apache/htrace/impl/HBaseTestUtil.java | 24 ++-- .../htrace/impl/TestHBaseSpanReceiver.java | 20 ++- 9 files changed, 452 insertions(+), 298 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/ad47b1a3/htrace-core/src/main/java/org/apache/htrace/SpanReceiverBuilder.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/SpanReceiverBuilder.java b/htrace-core/src/main/java/org/apache/htrace/SpanReceiverBuilder.java new file mode 100644 index 0000000..45d2872 --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/SpanReceiverBuilder.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 org.apache.htrace; + +import java.lang.reflect.Constructor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * A {@link SpanReceiver} builder. It defaults finding class of span receiver to build in + * the passed in configuration using the {@link #SPAN_RECEIVER_CONF_KEY} key. + */ +public class SpanReceiverBuilder { + static final Log LOG = LogFactory.getLog(SpanReceiverBuilder.class); + + public final static String SPAN_RECEIVER_CONF_KEY = "span.receiver"; + private final static ClassLoader classLoader = + SpanReceiverBuilder.class.getClassLoader(); + private final HTraceConfiguration conf; + private boolean logErrors; + private String spanReceiverClass; + + public SpanReceiverBuilder(HTraceConfiguration conf) { + this.conf = conf; + reset(); + } + + /** + * Set this builder back to defaults. + * @return This instance + */ + public SpanReceiverBuilder reset() { + this.logErrors = true; + this.spanReceiverClass = this.conf.get(SPAN_RECEIVER_CONF_KEY); + return this; + } + + public SpanReceiverBuilder spanReceiverClass(final String spanReceiverClass) { + this.spanReceiverClass = spanReceiverClass; + return this; + } + + /** + * Configure whether we should log errors during build(). + */ + public SpanReceiverBuilder logErrors(boolean logErrors) { + this.logErrors = logErrors; + return this; + } + + private void logError(String errorStr) { + if (!logErrors) { + return; + } + LOG.error(errorStr); + } + + private void logError(String errorStr, Throwable e) { + if (!logErrors) { + return; + } + LOG.error(errorStr, e); + } + + public SpanReceiver build() { + if ((this.spanReceiverClass == null) || + this.spanReceiverClass.isEmpty()) { + return null; + } + String str = spanReceiverClass; + if (!str.contains(".")) { + str = "org.apache.htrace.impl." + str; + } + Class cls = null; + try { + cls = classLoader.loadClass(str); + } catch (ClassNotFoundException e) { + logError("SpanReceiverBuilder cannot find SpanReceiver class " + str + + ": disabling span receiver."); + return null; + } + Constructor<SpanReceiver> ctor = null; + try { + ctor = cls.getConstructor(HTraceConfiguration.class); + } catch (NoSuchMethodException e) { + logError("SpanReceiverBuilder cannot find a constructor for class " + + str + "which takes an HTraceConfiguration. Disabling span " + + "receiver."); + return null; + } + try { + return ctor.newInstance(conf); + } catch (ReflectiveOperationException e) { + logError("SpanReceiverBuilder reflection error when constructing " + str + + ". Disabling span receiver.", e); + return null; + } catch (Throwable e) { + logError("SpanReceiverBuilder constructor error when constructing " + str + + ". Disabling span receiver.", e); + return null; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/ad47b1a3/htrace-core/src/main/java/org/apache/htrace/SpanReceiverFactory.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/SpanReceiverFactory.java b/htrace-core/src/main/java/org/apache/htrace/SpanReceiverFactory.java deleted file mode 100644 index 4d16ffb..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/SpanReceiverFactory.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF 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 org.apache.htrace; - -import java.lang.reflect.Constructor; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class SpanReceiverFactory { - static final Log LOG = LogFactory.getLog(SpanReceiverFactory.class); - - public final static String SPAN_RECEIVER_CONF_KEY = "span.receiver"; - private final static ClassLoader classLoader = - SpanReceiverFactory.class.getClassLoader(); - private final HTraceConfiguration conf; - private boolean logErrors = true; - - public SpanReceiverFactory(HTraceConfiguration conf) { - this.conf = conf; - } - - /** - * Configure whether we should log errors during build(). - */ - public SpanReceiverFactory logErrors(boolean logErrors) { - this.logErrors = logErrors; - return this; - } - - private void logError(String errorStr) { - if (!logErrors) { - return; - } - LOG.error(errorStr); - } - - private void logError(String errorStr, Throwable e) { - if (!logErrors) { - return; - } - LOG.error(errorStr, e); - } - - public SpanReceiver build() { - String str = conf.get(SPAN_RECEIVER_CONF_KEY); - if ((str == null) || str.isEmpty()) { - return null; - } - if (!str.contains(".")) { - str = "org.apache.htrace.impl." + str; - } - Class cls = null; - try { - cls = classLoader.loadClass(str); - } catch (ClassNotFoundException e) { - logError("SpanReceiverFactory cannot find SpanReceiver class " + str + - ": disabling span receiver."); - return null; - } - Constructor<SpanReceiver> ctor = null; - try { - ctor = cls.getConstructor(HTraceConfiguration.class); - } catch (NoSuchMethodException e) { - logError("SpanReceiverFactory cannot find a constructor for class " + - str + "which takes an HTraceConfiguration. Disabling span " + - "receiver."); - return null; - } - try { - return ctor.newInstance(conf); - } catch (ReflectiveOperationException e) { - logError("SpanReceiverFactory reflection error when constructing " + str + - ". Disabling span receiver.", e); - return null; - } catch (Throwable e) { - logError("SpanReceiverFactory constructor error when constructing " + str + - ". Disabling span receiver.", e); - return null; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/ad47b1a3/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverBuilder.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverBuilder.java b/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverBuilder.java new file mode 100644 index 0000000..16536af --- /dev/null +++ b/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverBuilder.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 org.apache.htrace; + +import org.apache.htrace.impl.LocalFileSpanReceiver; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class TestSpanReceiverBuilder { + /** + * Test that if no span receiver is configured, the builder returns null. + */ + @Test + public void testGetNullSpanReceiver() { + SpanReceiverBuilder builder = + new SpanReceiverBuilder(HTraceConfiguration.EMPTY).logErrors(false); + SpanReceiver rcvr = builder.build(); + Assert.assertEquals(null, rcvr); + } + + private static SpanReceiver createSpanReceiver(Map<String, String> m) { + HTraceConfiguration hconf = HTraceConfiguration.fromMap(m); + SpanReceiverBuilder builder = + new SpanReceiverBuilder(hconf). + logErrors(false); + return builder.build(); + } + + /** + * Test getting various SpanReceiver objects. + */ + @Test + public void testGetSpanReceivers() throws Exception { + HashMap<String, String> confMap = new HashMap<String, String>(); + + // Create LocalFileSpanReceiver + confMap.put(LocalFileSpanReceiver.PATH_KEY, "/tmp/foo"); + confMap.put(SpanReceiverBuilder.SPAN_RECEIVER_CONF_KEY, + "org.apache.htrace.impl.LocalFileSpanReceiver"); + SpanReceiver rcvr = createSpanReceiver(confMap); + Assert.assertEquals("org.apache.htrace.impl.LocalFileSpanReceiver", + rcvr.getClass().getName()); + rcvr.close(); + + // Create POJOSpanReceiver + confMap.remove(LocalFileSpanReceiver.PATH_KEY); + confMap.put(SpanReceiverBuilder.SPAN_RECEIVER_CONF_KEY, "POJOSpanReceiver"); + rcvr = createSpanReceiver(confMap); + Assert.assertEquals("org.apache.htrace.impl.POJOSpanReceiver", + rcvr.getClass().getName()); + rcvr.close(); + + // Create StandardOutSpanReceiver + confMap.remove(LocalFileSpanReceiver.PATH_KEY); + confMap.put(SpanReceiverBuilder.SPAN_RECEIVER_CONF_KEY, + "org.apache.htrace.impl.StandardOutSpanReceiver"); + rcvr = createSpanReceiver(confMap); + Assert.assertEquals("org.apache.htrace.impl.StandardOutSpanReceiver", + rcvr.getClass().getName()); + rcvr.close(); + } + + public static class TestSpanReceiver implements SpanReceiver { + final static String SUCCEEDS = "test.span.receiver.succeeds"; + + public TestSpanReceiver(HTraceConfiguration conf) { + if (conf.get(SUCCEEDS) == null) { + throw new RuntimeException("Can't create TestSpanReceiver: " + + "invalid configuration."); + } + } + + @Override + public void receiveSpan(Span span) { + } + + @Override + public void close() throws IOException { + } + } + + /** + * Test trying to create a SpanReceiver that experiences an error in the + * constructor. + */ + @Test + public void testGetSpanReceiverWithConstructorError() throws Exception { + HashMap<String, String> confMap = new HashMap<String, String>(); + + // Create TestSpanReceiver + confMap.put(SpanReceiverBuilder.SPAN_RECEIVER_CONF_KEY, + TestSpanReceiver.class.getName()); + confMap.put(TestSpanReceiver.SUCCEEDS, "true"); + SpanReceiver rcvr = createSpanReceiver(confMap); + Assert.assertEquals(TestSpanReceiver.class.getName(), + rcvr.getClass().getName()); + rcvr.close(); + + // Fail to create TestSpanReceiver + confMap.remove(TestSpanReceiver.SUCCEEDS); + rcvr = createSpanReceiver(confMap); + Assert.assertEquals(null, rcvr); + } +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/ad47b1a3/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverFactory.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverFactory.java b/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverFactory.java deleted file mode 100644 index 87b5085..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverFactory.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF 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 org.apache.htrace; - -import org.apache.htrace.impl.LocalFileSpanReceiver; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; - -public class TestSpanReceiverFactory { - /** - * Test that if no span receiver is configured, the factory returns null. - */ - @Test - public void testGetNullSpanReceiver() { - SpanReceiverFactory factory = - new SpanReceiverFactory(HTraceConfiguration.EMPTY).logErrors(false); - SpanReceiver rcvr = factory.build(); - Assert.assertEquals(null, rcvr); - } - - private static SpanReceiver createSpanReceiver(Map<String, String> m) { - HTraceConfiguration hconf = HTraceConfiguration.fromMap(m); - SpanReceiverFactory factory = - new SpanReceiverFactory(hconf). - logErrors(false); - return factory.build(); - } - - /** - * Test getting various SpanReceiver objects. - */ - @Test - public void testGetSpanReceivers() throws Exception { - HashMap<String, String> confMap = new HashMap<String, String>(); - - // Create LocalFileSpanReceiver - confMap.put(LocalFileSpanReceiver.PATH_KEY, "/tmp/foo"); - confMap.put(SpanReceiverFactory.SPAN_RECEIVER_CONF_KEY, - "org.apache.htrace.impl.LocalFileSpanReceiver"); - SpanReceiver rcvr = createSpanReceiver(confMap); - Assert.assertEquals("org.apache.htrace.impl.LocalFileSpanReceiver", - rcvr.getClass().getName()); - rcvr.close(); - - // Create POJOSpanReceiver - confMap.remove(LocalFileSpanReceiver.PATH_KEY); - confMap.put(SpanReceiverFactory.SPAN_RECEIVER_CONF_KEY, "POJOSpanReceiver"); - rcvr = createSpanReceiver(confMap); - Assert.assertEquals("org.apache.htrace.impl.POJOSpanReceiver", - rcvr.getClass().getName()); - rcvr.close(); - - // Create StandardOutSpanReceiver - confMap.remove(LocalFileSpanReceiver.PATH_KEY); - confMap.put(SpanReceiverFactory.SPAN_RECEIVER_CONF_KEY, - "org.apache.htrace.impl.StandardOutSpanReceiver"); - rcvr = createSpanReceiver(confMap); - Assert.assertEquals("org.apache.htrace.impl.StandardOutSpanReceiver", - rcvr.getClass().getName()); - rcvr.close(); - } - - public static class TestSpanReceiver implements SpanReceiver { - final static String SUCCEEDS = "test.span.receiver.succeeds"; - - public TestSpanReceiver(HTraceConfiguration conf) { - if (conf.get(SUCCEEDS) == null) { - throw new RuntimeException("Can't create TestSpanReceiver: " + - "invalid configuration."); - } - } - - @Override - public void receiveSpan(Span span) { - } - - @Override - public void close() throws IOException { - } - } - - /** - * Test trying to create a SpanReceiver that experiences an error in the - * constructor. - */ - @Test - public void testGetSpanReceiverWithConstructorError() throws Exception { - HashMap<String, String> confMap = new HashMap<String, String>(); - - // Create TestSpanReceiver - confMap.put(SpanReceiverFactory.SPAN_RECEIVER_CONF_KEY, - TestSpanReceiver.class.getName()); - confMap.put(TestSpanReceiver.SUCCEEDS, "true"); - SpanReceiver rcvr = createSpanReceiver(confMap); - Assert.assertEquals(TestSpanReceiver.class.getName(), - rcvr.getClass().getName()); - rcvr.close(); - - // Fail to create TestSpanReceiver - confMap.remove(TestSpanReceiver.SUCCEEDS); - rcvr = createSpanReceiver(confMap); - Assert.assertEquals(null, rcvr); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/ad47b1a3/htrace-hbase/src/main/java/org/apache/htrace/HBaseHTraceConfiguration.java ---------------------------------------------------------------------- diff --git a/htrace-hbase/src/main/java/org/apache/htrace/HBaseHTraceConfiguration.java b/htrace-hbase/src/main/java/org/apache/htrace/HBaseHTraceConfiguration.java new file mode 100644 index 0000000..86401bf --- /dev/null +++ b/htrace-hbase/src/main/java/org/apache/htrace/HBaseHTraceConfiguration.java @@ -0,0 +1,52 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 org.apache.htrace; + +import org.apache.hadoop.conf.Configuration; +import org.apache.htrace.HTraceConfiguration; + +/** + * Meshes {@link HTraceConfiguration} to {@link Configuration} + * @author stack + * + */ +public class HBaseHTraceConfiguration extends HTraceConfiguration { + public static final String KEY_PREFIX = "hbase.htrace."; + private final Configuration conf; + + public HBaseHTraceConfiguration(Configuration conf) { + this.conf = conf; + } + + @Override + public String get(String key) { + return conf.get(KEY_PREFIX + key); + } + + @Override + public String get(String key, String defaultValue) { + return conf.get(KEY_PREFIX + key, defaultValue); + + } + + @Override + public boolean getBoolean(String key, boolean defaultValue) { + return conf.getBoolean(KEY_PREFIX + key, defaultValue); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/ad47b1a3/htrace-hbase/src/main/java/org/apache/htrace/HBaseSpanReceiverHost.java ---------------------------------------------------------------------- diff --git a/htrace-hbase/src/main/java/org/apache/htrace/HBaseSpanReceiverHost.java b/htrace-hbase/src/main/java/org/apache/htrace/HBaseSpanReceiverHost.java new file mode 100644 index 0000000..a6c8382 --- /dev/null +++ b/htrace-hbase/src/main/java/org/apache/htrace/HBaseSpanReceiverHost.java @@ -0,0 +1,105 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 org.apache.htrace; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.htrace.SpanReceiver; +import org.apache.htrace.Trace; + +/** + * This class provides functions for reading the names of SpanReceivers from + * hbase-site.xml, adding those SpanReceivers to the Tracer, and closing those + * SpanReceivers when appropriate. + */ +public class HBaseSpanReceiverHost { + public static final String SPAN_RECEIVERS_CONF_KEY = "hbase.trace.spanreceiver.classes"; + private static final Log LOG = LogFactory.getLog(HBaseSpanReceiverHost.class); + private Collection<SpanReceiver> receivers; + private Configuration conf; + private boolean closed = false; + + private static enum SingletonHolder { + INSTANCE; + Object lock = new Object(); + HBaseSpanReceiverHost host = null; + } + + public static HBaseSpanReceiverHost getInstance(Configuration conf) { + synchronized (SingletonHolder.INSTANCE.lock) { + if (SingletonHolder.INSTANCE.host != null) { + return SingletonHolder.INSTANCE.host; + } + + HBaseSpanReceiverHost host = new HBaseSpanReceiverHost(conf); + host.loadSpanReceivers(); + SingletonHolder.INSTANCE.host = host; + return SingletonHolder.INSTANCE.host; + } + + } + + HBaseSpanReceiverHost(Configuration conf) { + receivers = new HashSet<SpanReceiver>(); + this.conf = conf; + } + + /** + * Reads the names of classes specified in the + * "hbase.trace.spanreceiver.classes" property and instantiates and registers + * them with the Tracer as SpanReceiver's. + * + */ + public void loadSpanReceivers() { + String[] receiverNames = conf.getStrings(SPAN_RECEIVERS_CONF_KEY); + if (receiverNames == null || receiverNames.length == 0) { + return; + } + SpanReceiverBuilder builder = new SpanReceiverBuilder(new HBaseHTraceConfiguration(this.conf)); + for (String className : receiverNames) { + SpanReceiver receiver = builder.spanReceiverClass(className.trim()).build(); + if (receiver != null) { + receivers.add(receiver); + LOG.info("SpanReceiver " + className + " was loaded successfully."); + } + } + for (SpanReceiver rcvr : receivers) { + Trace.addReceiver(rcvr); + } + } + + /** + * Calls close() on all SpanReceivers created by this HBaseSpanReceiverHost. + */ + public synchronized void closeReceivers() { + if (closed) return; + closed = true; + for (SpanReceiver rcvr : receivers) { + try { + rcvr.close(); + } catch (IOException e) { + LOG.warn("Unable to close SpanReceiver correctly: " + e.getMessage(), e); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/ad47b1a3/htrace-hbase/src/main/java/org/apache/htrace/impl/HBaseSpanReceiver.java ---------------------------------------------------------------------- diff --git a/htrace-hbase/src/main/java/org/apache/htrace/impl/HBaseSpanReceiver.java b/htrace-hbase/src/main/java/org/apache/htrace/impl/HBaseSpanReceiver.java index 4a499ec..b03291e 100644 --- a/htrace-hbase/src/main/java/org/apache/htrace/impl/HBaseSpanReceiver.java +++ b/htrace-hbase/src/main/java/org/apache/htrace/impl/HBaseSpanReceiver.java @@ -17,43 +17,40 @@ package org.apache.htrace.impl; -import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HBaseConfiguration; -import org.apache.hadoop.hbase.client.HConnection; -import org.apache.hadoop.hbase.client.HConnectionManager; -import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Connection; +import org.apache.hadoop.hbase.client.ConnectionFactory; import org.apache.hadoop.hbase.client.Put; -import org.apache.hadoop.hbase.trace.HBaseHTraceConfiguration; +import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.htrace.HBaseHTraceConfiguration; import org.apache.htrace.HTraceConfiguration; import org.apache.htrace.Sampler; import org.apache.htrace.Span; import org.apache.htrace.SpanReceiver; +import org.apache.htrace.SpanReceiverBuilder; import org.apache.htrace.TimelineAnnotation; import org.apache.htrace.Trace; import org.apache.htrace.TraceScope; import org.apache.htrace.protobuf.generated.SpanProtos; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; +import com.google.common.util.concurrent.ThreadFactoryBuilder; /** * HBase is an open source distributed datastore. @@ -112,16 +109,13 @@ public class HBaseSpanReceiver implements SpanReceiver { */ private final ThreadFactory tf; - //////////////////// - /// Variables that will change on each call to configure() - /////////////////// private ExecutorService service; - private HTraceConfiguration conf; - private Configuration hconf; - private byte[] table; - private byte[] cf; - private byte[] icf; - private int maxSpanBatchSize; + private final HTraceConfiguration conf; + private final Configuration hconf; + private final byte[] table; + private final byte[] cf; + private final byte[] icf; + private final int maxSpanBatchSize; public HBaseSpanReceiver(HTraceConfiguration conf) { this.queue = new ArrayBlockingQueue<Span>(1000); @@ -155,8 +149,8 @@ public class HBaseSpanReceiver implements SpanReceiver { } private class WriteSpanRunnable implements Runnable { - private HConnection hconnection; - private HTableInterface htable; + private Connection hconnection; + private Table htable; public WriteSpanRunnable() { } @@ -285,8 +279,8 @@ public class HBaseSpanReceiver implements SpanReceiver { private void startClient() { if (this.htable == null) { try { - hconnection = HConnectionManager.createConnection(hconf); - htable = hconnection.getTable(table); + hconnection = ConnectionFactory.createConnection(hconf); + htable = hconnection.getTable(TableName.valueOf(table)); } catch (IOException e) { LOG.warn("Failed to create HBase connection. " + e.getMessage()); } @@ -331,28 +325,25 @@ public class HBaseSpanReceiver implements SpanReceiver { } /** - * Run basic test. + * Run basic test. Adds span to an existing htrace table in an existing hbase setup. + * Requires a running hbase to send the traces too with an already created trace + * table (Default table name is 'htrace' with column families 's' and 'i'). * @throws IOException - * - * - * TODO: !!!!! FIX !!!! Circular dependency back to HBase!!! - * + */ public static void main(String[] args) throws Exception { - HBaseSpanReceiver receiver = new HBaseSpanReceiver(); - receiver.configure(new HBaseHTraceConfiguration(HBaseConfiguration.create())); + SpanReceiverBuilder builder = + new SpanReceiverBuilder(new HBaseHTraceConfiguration(HBaseConfiguration.create())); + SpanReceiver receiver = + builder.spanReceiverClass(HBaseSpanReceiver.class.getName()).build(); Trace.addReceiver(receiver); - TraceScope parent = - Trace.startSpan("HBaseSpanReceiver.main.parent", Sampler.ALWAYS); + TraceScope parent = Trace.startSpan("HBaseSpanReceiver.main.parent", Sampler.ALWAYS); Thread.sleep(10); long traceid = parent.getSpan().getTraceId(); - TraceScope child1 = - Trace.startSpan("HBaseSpanReceiver.main.child.1"); + TraceScope child1 = Trace.startSpan("HBaseSpanReceiver.main.child.1"); Thread.sleep(10); - TraceScope child2 = - Trace.startSpan("HBaseSpanReceiver.main.child.2", parent.getSpan()); + TraceScope child2 = Trace.startSpan("HBaseSpanReceiver.main.child.2", parent.getSpan()); Thread.sleep(10); - TraceScope gchild = - Trace.startSpan("HBaseSpanReceiver.main.grandchild"); + TraceScope gchild = Trace.startSpan("HBaseSpanReceiver.main.grandchild"); Trace.addTimelineAnnotation("annotation 1."); Thread.sleep(10); Trace.addTimelineAnnotation("annotation 2."); @@ -365,5 +356,4 @@ public class HBaseSpanReceiver implements SpanReceiver { receiver.close(); System.out.println("trace id: " + traceid); } - */ -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/ad47b1a3/htrace-hbase/src/test/java/org/apache/htrace/impl/HBaseTestUtil.java ---------------------------------------------------------------------- diff --git a/htrace-hbase/src/test/java/org/apache/htrace/impl/HBaseTestUtil.java b/htrace-hbase/src/test/java/org/apache/htrace/impl/HBaseTestUtil.java index bcc5d27..8743f8a 100644 --- a/htrace-hbase/src/test/java/org/apache/htrace/impl/HBaseTestUtil.java +++ b/htrace-hbase/src/test/java/org/apache/htrace/impl/HBaseTestUtil.java @@ -19,24 +19,19 @@ package org.apache.htrace.impl; import java.io.IOException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HConstants; -import org.apache.hadoop.hbase.client.HTableInterface; -import org.apache.hadoop.hbase.trace.HBaseHTraceConfiguration; +import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.util.Bytes; -import org.apache.htrace.HTraceConfiguration; +import org.apache.htrace.HBaseHTraceConfiguration; import org.apache.htrace.SpanReceiver; -import org.apache.htrace.impl.HBaseSpanReceiver; +import org.apache.htrace.SpanReceiverBuilder; import org.junit.Assert; public class HBaseTestUtil { - private static final Log LOG = LogFactory.getLog(HBaseTestUtil.class); - public static Configuration configure(Configuration conf) { Configuration hconf = HBaseConfiguration.create(conf); hconf.set(HBaseHTraceConfiguration.KEY_PREFIX + @@ -51,8 +46,8 @@ public class HBaseTestUtil { return hconf; } - public static HTableInterface createTable(HBaseTestingUtility util) { - HTableInterface htable = null; + public static Table createTable(HBaseTestingUtility util) { + Table htable = null; try { htable = util.createTable(Bytes.toBytes(HBaseSpanReceiver.DEFAULT_TABLE), new byte[][]{Bytes.toBytes(HBaseSpanReceiver.DEFAULT_COLUMNFAMILY), @@ -64,12 +59,7 @@ public class HBaseTestUtil { } public static SpanReceiver startReceiver(Configuration conf) { - /* TODO: FIX!!!!! CIRCULAR DEPENDENCY BACK TO HBASE - SpanReceiver receiver = new HBaseSpanReceiver(); - receiver.configure(new HBaseHTraceConfiguration(conf)); - return receiver; - */ - return null; + return new SpanReceiverBuilder(new HBaseHTraceConfiguration(conf)).build(); } public static SpanReceiver startReceiver(HBaseTestingUtility util) { @@ -86,4 +76,4 @@ public class HBaseTestUtil { } } } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/ad47b1a3/htrace-hbase/src/test/java/org/apache/htrace/impl/TestHBaseSpanReceiver.java ---------------------------------------------------------------------- diff --git a/htrace-hbase/src/test/java/org/apache/htrace/impl/TestHBaseSpanReceiver.java b/htrace-hbase/src/test/java/org/apache/htrace/impl/TestHBaseSpanReceiver.java index 4d6d15c..9fd3ca8 100644 --- a/htrace-hbase/src/test/java/org/apache/htrace/impl/TestHBaseSpanReceiver.java +++ b/htrace-hbase/src/test/java/org/apache/htrace/impl/TestHBaseSpanReceiver.java @@ -17,11 +17,9 @@ package org.apache.htrace.impl; -import com.google.common.collect.Multimap; - -import java.io.InputStream; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -32,9 +30,8 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.Cell; -import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.HBaseTestingUtility; -import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Scan; @@ -42,15 +39,16 @@ import org.apache.hadoop.hbase.util.Bytes; import org.apache.htrace.Span; import org.apache.htrace.SpanReceiver; import org.apache.htrace.TimelineAnnotation; +import org.apache.htrace.TraceCreator; import org.apache.htrace.TraceTree; -import org.apache.htrace.impl.HBaseSpanReceiver; import org.apache.htrace.protobuf.generated.SpanProtos; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Test; import org.junit.Ignore; -import org.junit.Assert; -import org.apache.htrace.TraceCreator; +import org.junit.Test; + +import com.google.common.collect.Multimap; public class TestHBaseSpanReceiver { @@ -70,7 +68,7 @@ public class TestHBaseSpanReceiver { // Reenable after fix circular dependency @Ignore @Test public void testHBaseSpanReceiver() { - HTableInterface htable = HBaseTestUtil.createTable(UTIL); + Table htable = HBaseTestUtil.createTable(UTIL); SpanReceiver receiver = HBaseTestUtil.startReceiver(UTIL); TraceCreator tc = new TraceCreator(receiver); tc.createThreadedTrace(); @@ -108,7 +106,6 @@ public class TestHBaseSpanReceiver { Assert.assertTrue(descs.keySet().contains(TraceCreator.SIMPLE_TRACE_ROOT)); Assert.assertTrue(descs.keySet().contains(TraceCreator.THREADED_TRACE_ROOT)); - /** TODO: FIX!!!!!! Multimap<Long, Span> spansByParentId = traceTree.getSpansByParentIdMap(); Span rpcRoot = descs.get(TraceCreator.RPC_TRACE_ROOT); Assert.assertEquals(1, spansByParentId.get(rpcRoot.getSpanId()).size()); @@ -137,7 +134,6 @@ public class TestHBaseSpanReceiver { } catch (IOException e) { Assert.fail("failed to get spans from index family. " + e.getMessage()); } - */ } private class TestSpan implements Span {
