diff --git a/.gitignore b/.gitignore
index 378eac25d3..a8b79c7bf1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,9 @@
+INSTALL
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
build
+config.log
+config.status
+configure
diff --git a/Makefile b/Makefile
deleted file mode 100644
index ffddca685d..0000000000
--- a/Makefile
+++ /dev/null
@@ -1,248 +0,0 @@
-# Copyright (C) 2010 The OpenTSDB Authors.
-#
-# This library is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library. If not, see .
-
-all: jar
-# TODO(tsuna): Use automake to avoid relying on GNU make extensions.
-
-top_builddir = build
-package = net.opentsdb
-spec_title = OpenTSDB
-spec_vendor = StumbleUpon, Inc.
-spec_version = 1.0
-BUILT_SOURCES = src/BuildData.java
-tsdb_JAVA = \
- src/core/Aggregator.java \
- src/core/Aggregators.java \
- src/core/Const.java \
- src/core/DataPoint.java \
- src/core/DataPoints.java \
- src/core/DataPointsIterator.java \
- src/core/IncomingDataPoints.java \
- src/core/IllegalDataException.java \
- src/core/Query.java \
- src/core/RowKey.java \
- src/core/RowSeq.java \
- src/core/SeekableView.java \
- src/core/Span.java \
- src/core/SpanGroup.java \
- src/core/TSDB.java \
- src/core/TSDBInterface.java \
- src/core/Tags.java \
- src/core/TsdbQuery.java \
- src/core/WritableDataPoints.java \
- src/graph/Plot.java \
- src/stats/Histogram.java \
- src/stats/StatsCollector.java \
- src/tools/ArgP.java \
- src/tools/CliOptions.java \
- src/tools/CliQuery.java \
- src/tools/Core.java \
- src/tools/DumpSeries.java \
- src/tools/Fsck.java \
- src/tools/TSDMain.java \
- src/tools/TextImporter.java \
- src/tools/UidManager.java \
- src/tsd/BadRequestException.java \
- src/tsd/ConnectionManager.java \
- src/tsd/GnuplotException.java \
- src/tsd/GraphHandler.java \
- src/tsd/HttpQuery.java \
- src/tsd/HttpRpc.java \
- src/tsd/LogsRpc.java \
- src/tsd/PipelineFactory.java \
- src/tsd/PutDataPointRpc.java \
- src/tsd/RpcHandler.java \
- src/tsd/StaticFileRpc.java \
- src/tsd/TelnetRpc.java \
- src/tsd/WordSplitter.java \
- src/uid/NoSuchUniqueId.java \
- src/uid/NoSuchUniqueName.java \
- src/uid/UniqueId.java \
- src/uid/UniqueIdInterface.java \
-
-tsdb_LIBADD = \
- third_party/hbase/hbaseasync-1.0.jar \
- third_party/logback/logback-classic-0.9.24.jar \
- third_party/logback/logback-core-0.9.24.jar \
- third_party/netty/netty-3.2.3.Final.jar \
- third_party/slf4j/jcl-over-slf4j-1.6.1.jar \
- third_party/slf4j/log4j-over-slf4j-1.6.1.jar \
- third_party/slf4j/slf4j-api-1.6.1.jar \
- third_party/suasync/suasync-1.0.jar \
- third_party/zookeeper/zookeeper-3.3.1.jar \
-
-test_JAVA = \
- src/core/TestTags.java \
- src/stats/TestHistogram.java \
- src/tsd/TestGraphHandler.java \
- src/uid/TestNoSuchUniqueId.java \
- src/uid/TestUniqueId.java \
-
-test_LIBADD = \
- $(tsdb_LIBADD) \
- third_party/javassist/javassist-3.13.GA.jar \
- third_party/junit/junit-4.8.2.jar \
- third_party/mockito/mockito-1.8.5.jar \
- third_party/powermock/powermock-mockito-1.4.5.jar \
- $(jar)
-
-httpui_JAVA = \
- src/tsd/client/DateTimeBox.java \
- src/tsd/client/EventsHandler.java \
- src/tsd/client/GotJsonCallback.java \
- src/tsd/client/MetricForm.java \
- src/tsd/client/QueryUi.java \
- src/tsd/client/RemoteOracle.java \
- src/tsd/client/ValidatedTextBox.java \
-
-httpui_DEPENDENCIES = src/tsd/QueryUi.gwt.xml
-
-dist_pkgdata_DATA = \
- src/tsd/static/favicon.ico \
-
-GWT_DEV = third_party/gwt/gwt-dev-2.0.4.jar
-GWT_SDK = third_party/gwt/gwt-user-2.0.4.jar
-GWTC_JVM_ARGS = # add jvmarg -Xss16M or similar if you see a StackOverflowError
-GWTC_ARGS = -ea # Additional arguments like -style PRETTY or -logLevel DEBUG
-
-TESTS = $(test_JAVA:src/%.java=$(top_builddir)/$(package_dir)/%.class)
-AM_JAVACFLAGS = -Xlint -source 6
-JVM_ARGS =
-package_dir = $(subst .,/,$(package))
-classes=$(tsdb_JAVA:src/%.java=$(top_builddir)/$(package_dir)/%.class) \
- $(BUILT_SOURCES:src/%.java=$(top_builddir)/$(package_dir)/%.class)
-jar = $(top_builddir)/tsdb-$(spec_version).jar
-test_classes=$(test_JAVA:src/%.java=$(top_builddir)/$(package_dir)/%.class)
-
-src/BuildData.java: .git/HEAD $(tsdb_JAVA) ./buildtools/gen_build_data.sh
- ./buildtools/gen_build_data.sh src/BuildData.java $(package)
-
-jar: $(jar) $(TESTS) $(BUILT_SOURCES) $(top_builddir)/.gwtc-stamp
-
-get_dep_classpath = `echo $(tsdb_LIBADD) | tr ' ' ':'`
-$(top_builddir)/.javac-stamp: $(tsdb_JAVA) $(BUILT_SOURCES) $(tsdb_LIBADD)
- @mkdir -p $(top_builddir)
- javac $(AM_JAVACFLAGS) -cp $(get_dep_classpath) \
- -d $(top_builddir) $(tsdb_JAVA) $(BUILT_SOURCES)
- @touch "$@"
-
-# The GWT compiler is way too slow, that's not very Googley. So we save the
-# MD5 of the files we compile in the stamp file and everytime `make' things it
-# needs to recompile the GWT code, we verify whether the code really changed
-# or whether it's just a file that was touched (which happens frequently when
-# using Git while rebasing and whatnot).
-gwtc: $(top_builddir)/.gwtc-stamp
-MD5 = md5 # TODO(tsuna): Detect the right command to use at configure time.
-$(top_builddir)/.gwtc-stamp: $(httpui_JAVA) $(httpui_DEPENDENCIES)
- @mkdir -p $(top_builddir)/gwt
- cat $(httpui_JAVA) | $(MD5) >"$@-t"
- cmp -s "$@" "$@-t" || \
- java $(GWTC_JVM_ARGS) -cp $(GWT_DEV):$(GWT_SDK):src com.google.gwt.dev.Compiler \
- $(GWTC_ARGS) -war $(top_builddir)/gwt tsd.QueryUi
- mv "$@-t" "$@"
-
-DEV_TSD_ARGS = \
- --port=$(DEV_TSD_PORT) \
- --staticroot=$(DEV_TSD_STATICROOT) --cachedir=$(DEV_TSD_CACHEDIR)
-DEV_TSD_PORT = 4242
-DEV_TSD_STATICROOT = $(top_builddir)/staticroot
-DEV_TSD_CACHEDIR = /tmp/tsd
-GWT_DEV_URL = http://127.0.0.1:$(DEV_TSD_PORT)/
-
-GWT_DEV_ARGS = -Xmx512m # The development mode is a memory hog.
-gwtdev: $(top_builddir)/.gwtc-stamp
- java $(GWT_DEV_ARGS) -ea -cp $(GWT_DEV):$(GWT_SDK):src com.google.gwt.dev.DevMode \
- -startupUrl $(GWT_DEV_URL) -noserver -war $(top_builddir)/gwt tsd.QueryUi
-
-staticroot: jar $(top_builddir)/.staticroot-stamp
-
-gwttsd: staticroot
- ./src/tsdb tsd $(DEV_TSD_ARGS)
-
-$(top_builddir)/.staticroot-stamp: $(dist_pkgdata_DATA) $(top_builddir)/.gwtc-stamp
- mkdir -p $(DEV_TSD_STATICROOT)
- cp $(dist_pkgdata_DATA) $(DEV_TSD_STATICROOT)
- find -L $(DEV_TSD_STATICROOT) -type l -delete
- p=`pwd`/$(top_builddir)/gwt/queryui && cd $(DEV_TSD_STATICROOT) \
- && for i in $$p/*; do ln -s -f "$$i" || break; done
- find -L $(DEV_TSD_STATICROOT)/gwt -type f | xargs touch
- @touch $(top_builddir)/.staticroot-stamp
-
-get_runtime_dep_classpath = `echo $(test_LIBADD) | tr ' ' ':'`
-$(test_classes): $(jar) $(test_JAVA) $(test_LIBADD)
- javac $(AM_JAVACFLAGS) -cp $(get_runtime_dep_classpath) \
- -d $(top_builddir) $(test_JAVA)
-
-printcp:
- @echo $(tsdb_LIBADD) $(jar) | tr ' ' '\n' | sed "s:^:`pwd`/:" | tr '\n' ':'
-
-classes_with_nested_classes = $(classes:$(top_builddir)/%.class=%*.class)
-test_classes_with_nested_classes = $(test_classes:$(top_builddir)/%.class=%*.class)
-
-# Little set script to make a pretty-ish banner.
-BANNER = sed 's/^.*/ & /;h;s/./=/g;p;x;p;x'
-check: $(TESTS)
- classes=`cd $(top_builddir) && echo $(test_classes_with_nested_classes)` && \
- success=: && cp="$(get_runtime_dep_classpath):$(top_builddir)" && \
- for i in $$classes; do \
- case $$i in (*[$$]*) continue;; esac; \
- echo "Running tests for `basename $$i .class`" | $(BANNER); \
- java -ea $(JVM_ARGS) -cp "$$cp" org.junit.runner.JUnitCore `echo $${i%.class} | tr / .` $(ARGS) || success=false; \
- done && $$success
-
-pkg_version = \
- `git rev-list --pretty=format:%h HEAD --max-count=1 | sed 1d || echo unknown`
-$(top_builddir)/manifest: $(top_builddir)/.javac-stamp .git/HEAD
- { echo "Specification-Title: $(spec_title)"; \
- echo "Specification-Version: $(spec_version)"; \
- echo "Specification-Vendor: $(spec_vendor)"; \
- echo "Implementation-Title: $(package)"; \
- echo "Implementation-Version: $(pkg_version)"; \
- echo "Implementation-Vendor: $(spec_vendor)"; } >"$@"
-
-$(jar): $(top_builddir)/manifest $(top_builddir)/.javac-stamp $(classes)
- cd $(top_builddir) && jar cfm `basename $(jar)` manifest $(classes_with_nested_classes) \
- || { rv=$$? && rm -f `basename $(jar)` && exit $$rv; }
-# ^^^^^^^^^^^^^^^^^^^^^^^
-# I've seen cases where `jar' exits with an error but leaves a partially built .jar file!
-
-doc: $(top_builddir)/api/index.html
-
-JDK_JAVADOC=http://download.oracle.com/javase/6/docs/api
-NETTY_JAVADOC=http://docs.jboss.org/netty/3.2/api
-$(top_builddir)/api/index.html: $(tsdb_JAVA) $(BUILT_SOURCES)
- javadoc -d $(top_builddir)/api -classpath $(get_dep_classpath) \
- -link $(JDK_JAVADOC) -link $(NETTY_JAVADOC) $(tsdb_JAVA) $(BUILT_SOURCES)
-
-clean:
- @rm -f $(top_builddir)/.javac-stamp $(top_builddir)/.gwtc-stamp* $(top_builddir)/.staticroot-stamp
- rm -rf $(top_builddir)/gwt $(top_builddir)/staticroot
- rm -f $(top_builddir)/manifest $(BUILT_SOURCES)
- cd $(top_builddir) || exit 0 && rm -f $(classes_with_nested_classes) $(test_classes_with_nested_classes)
- cd $(top_builddir) || exit 0 \
- && test -d $(package_dir) || exit 0 \
- && find $(package_dir) -depth -type d -exec rmdir {} ';' \
- && dir=$(package_dir) && dir=$${dir%/*} \
- && while test x"$$dir" != x"$${dir%/*}"; do \
- rmdir "$$dir" && dir=$${dir%/*} || break; \
- done \
- && rmdir "$$dir"
-
-distclean: clean
- rm -f $(jar)
- rm -rf $(top_builddir)/api
- test ! -d $(top_builddir) || rmdir $(top_builddir)
-
-.PHONY: all jar clean distclean doc check gwtc gwtdev staticroot gwttsd printcp
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000000..5a4ed7439b
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,311 @@
+# Copyright (C) 2011 The OpenTSDB Authors.
+#
+# This library is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see .
+
+ACLOCAL_AMFLAGS = -I build-aux
+
+all-am: jar staticroot
+
+package = net.opentsdb
+spec_title = OpenTSDB
+spec_vendor = StumbleUpon, Inc.
+jar := tsdb-$(PACKAGE_VERSION).jar
+builddata_SRC := src/BuildData.java
+BUILT_SOURCES = $(builddata_SRC)
+nodist_bin_SCRIPTS = tsdb
+dist_noinst_SCRIPTS = src/create_table.sh
+dist_pkgdata_SCRIPTS = src/mygnuplot.sh
+tsdb_SRC := \
+ src/core/Aggregator.java \
+ src/core/Aggregators.java \
+ src/core/Const.java \
+ src/core/DataPoint.java \
+ src/core/DataPoints.java \
+ src/core/DataPointsIterator.java \
+ src/core/IncomingDataPoints.java \
+ src/core/IllegalDataException.java \
+ src/core/Query.java \
+ src/core/RowKey.java \
+ src/core/RowSeq.java \
+ src/core/SeekableView.java \
+ src/core/Span.java \
+ src/core/SpanGroup.java \
+ src/core/TSDB.java \
+ src/core/TSDBInterface.java \
+ src/core/Tags.java \
+ src/core/TsdbQuery.java \
+ src/core/WritableDataPoints.java \
+ src/graph/Plot.java \
+ src/stats/Histogram.java \
+ src/stats/StatsCollector.java \
+ src/tools/ArgP.java \
+ src/tools/CliOptions.java \
+ src/tools/CliQuery.java \
+ src/tools/Core.java \
+ src/tools/DumpSeries.java \
+ src/tools/Fsck.java \
+ src/tools/TSDMain.java \
+ src/tools/TextImporter.java \
+ src/tools/UidManager.java \
+ src/tsd/BadRequestException.java \
+ src/tsd/ConnectionManager.java \
+ src/tsd/GnuplotException.java \
+ src/tsd/GraphHandler.java \
+ src/tsd/HttpQuery.java \
+ src/tsd/HttpRpc.java \
+ src/tsd/LogsRpc.java \
+ src/tsd/PipelineFactory.java \
+ src/tsd/PutDataPointRpc.java \
+ src/tsd/RpcHandler.java \
+ src/tsd/StaticFileRpc.java \
+ src/tsd/TelnetRpc.java \
+ src/tsd/WordSplitter.java \
+ src/uid/NoSuchUniqueId.java \
+ src/uid/NoSuchUniqueName.java \
+ src/uid/UniqueId.java \
+ src/uid/UniqueIdInterface.java
+
+tsdb_SRC_srcdir := $(tsdb_SRC:%=$(srcdir)/%)
+
+tsdb_DEPS := \
+ $(srcdir)/third_party/hbase/hbaseasync-1.0.jar \
+ $(srcdir)/third_party/logback/logback-classic-0.9.24.jar \
+ $(srcdir)/third_party/logback/logback-core-0.9.24.jar \
+ $(srcdir)/third_party/netty/netty-3.2.3.Final.jar \
+ $(srcdir)/third_party/slf4j/jcl-over-slf4j-1.6.1.jar \
+ $(srcdir)/third_party/slf4j/log4j-over-slf4j-1.6.1.jar \
+ $(srcdir)/third_party/slf4j/slf4j-api-1.6.1.jar \
+ $(srcdir)/third_party/suasync/suasync-1.0.jar \
+ $(srcdir)/third_party/zookeeper/zookeeper-3.3.1.jar
+
+# Install all the .jar files in pkgdatadir.
+pkgdata_DATA = $(tsdb_DEPS) $(jar)
+
+test_SRC := \
+ src/core/TestTags.java \
+ src/stats/TestHistogram.java \
+ src/tsd/TestGraphHandler.java \
+ src/uid/TestNoSuchUniqueId.java \
+ src/uid/TestUniqueId.java
+
+test_DEPS := \
+ $(tsdb_DEPS) \
+ $(srcdir)/third_party/javassist/javassist-3.13.GA.jar \
+ $(srcdir)/third_party/junit/junit-4.8.2.jar \
+ $(srcdir)/third_party/mockito/mockito-1.8.5.jar \
+ $(srcdir)/third_party/powermock/powermock-mockito-1.4.5.jar \
+ $(jar)
+
+httpui_SRC := \
+ src/tsd/client/DateTimeBox.java \
+ src/tsd/client/EventsHandler.java \
+ src/tsd/client/GotJsonCallback.java \
+ src/tsd/client/MetricForm.java \
+ src/tsd/client/QueryUi.java \
+ src/tsd/client/RemoteOracle.java \
+ src/tsd/client/ValidatedTextBox.java
+
+httpui_DEPS = src/tsd/QueryUi.gwt.xml
+
+dist_pkgdata_DATA = src/logback.xml
+dist_static_DATA = src/tsd/static/favicon.ico
+
+EXTRA_DIST = tsdb.in $(tsdb_SRC) $(test_SRC) third_party \
+ $(httpui_SRC) $(httpui_DEPS) \
+ bootstrap build.sh build-aux/gen_build_data.sh $(builddata_SRC)
+
+GWT_DEV := $(srcdir)/third_party/gwt/gwt-dev-2.0.4.jar
+GWT_SDK := $(srcdir)/third_party/gwt/gwt-user-2.0.4.jar
+GWTC_JVM_ARGS = # add jvmarg -Xss16M or similar if you see a StackOverflowError
+GWTC_ARGS = -ea # Additional arguments like -style PRETTY or -logLevel DEBUG
+
+package_dir := $(subst .,/,$(package))
+UNITTESTS := $(test_SRC:src/%.java=$(package_dir)/%.class)
+AM_JAVACFLAGS = -Xlint -source 6
+JVM_ARGS =
+classes := $(tsdb_SRC:src/%.java=$(package_dir)/%.class) \
+ $(builddata_SRC:src/%.java=$(package_dir)/%.class)
+test_classes := $(test_SRC:src/%.java=$(package_dir)/%.class)
+
+edit_tsdb_script := srcdir=''; test -f ./$$script.in || srcdir=$(srcdir)/; \
+ sed -e "s:@pkgdatadir[@]:$$pkgdatadir:g" \
+ -e "s:@abs_srcdir[@]:$$abs_srcdir:g" \
+ -e "s:@abs_builddir[@]:$$abs_builddir:g" \
+ $${srcdir}$$script.in >$$script.tmp
+
+tsdb: $(srcdir)/tsdb.in
+tsdb: Makefile
+ rm -f $@ $@.tmp
+ script=$@; pkgdatadir=''; \
+ abs_srcdir='$(abs_srcdir)'; abs_builddir='$(abs_builddir)'; \
+ $(edit_tsdb_script)
+ chmod +x $@.tmp
+ chmod a-w $@.tmp
+ mv $@.tmp $@
+
+# Adjust the paths in the 'tsdb' script after it's been installed.
+# This is kind of a hack, but I couldn't find a better way to adjust the paths
+# in the script before it gets installed...
+install-exec-hook:
+ script=tsdb; pkgdatadir='$(pkgdatadir)'; abs_srcdir=''; abs_builddir=''; \
+ $(edit_tsdb_script)
+ cat tsdb.tmp >"$(DESTDIR)$(bindir)/tsdb"
+ rm -f tsdb.tmp
+
+$(builddata_SRC): .git/HEAD $(tsdb_SRC) $(top_srcdir)/build-aux/gen_build_data.sh
+ $(MKDIR_P) `dirname "$(builddata_SRC)"`
+ $(srcdir)/build-aux/gen_build_data.sh $(builddata_SRC) $(package)
+
+jar: $(jar) $(UNITTESTS) .gwtc-stamp
+
+JAVA_COMPILE := $(JAVAC) $(AM_JAVACFLAGS) -d $(builddir)
+
+get_dep_classpath := `echo $(tsdb_DEPS) | tr ' ' ':'`
+.javac-stamp: $(tsdb_SRC) $(tsdb_DEPS)
+ @$(MKDIR_P) $(builddir)
+ $(JAVA_COMPILE) -cp $(get_dep_classpath) $(tsdb_SRC_srcdir) $(builddata_SRC)
+ @touch "$@"
+
+# The GWT compiler is way too slow, that's not very Googley. So we save the
+# MD5 of the files we compile in the stamp file and everytime `make' things it
+# needs to recompile the GWT code, we verify whether the code really changed
+# or whether it's just a file that was touched (which happens frequently when
+# using Git while rebasing and whatnot).
+gwtc: .gwtc-stamp
+.gwtc-stamp: $(httpui_SRC) $(httpui_DEPS)
+ @$(MKDIR_P) gwt
+ { cd $(srcdir) && cat $(httpui_SRC); } | $(MD5) >"$@-t"
+ cmp -s "$@" "$@-t" && exit 0; \
+ $(JAVA) $(GWTC_JVM_ARGS) -cp $(GWT_DEV):$(GWT_SDK):$(srcdir)/src com.google.gwt.dev.Compiler \
+ $(GWTC_ARGS) -war gwt tsd.QueryUi
+ @mv "$@-t" "$@"
+
+DEV_TSD_ARGS = \
+ --port=$(DEV_TSD_PORT) \
+ --staticroot=$(DEV_TSD_STATICROOT) --cachedir=$(DEV_TSD_CACHEDIR)
+DEV_TSD_PORT = 4242
+DEV_TSD_STATICROOT = staticroot
+DEV_TSD_CACHEDIR = /tmp/tsd
+GWT_DEV_URL = http://127.0.0.1:$(DEV_TSD_PORT)/
+
+GWT_DEV_ARGS = -Xmx512m # The development mode is a memory hog.
+gwtdev: .gwtc-stamp
+ $(JAVA) $(GWT_DEV_ARGS) -ea -cp $(GWT_DEV):$(GWT_SDK):src com.google.gwt.dev.DevMode \
+ -startupUrl $(GWT_DEV_URL) -noserver -war gwt tsd.QueryUi
+
+staticroot: jar .staticroot-stamp
+
+gwttsd: staticroot
+ ./tsdb tsd $(DEV_TSD_ARGS)
+
+.staticroot-stamp: $(dist_static_DATA) .gwtc-stamp
+ $(MKDIR_P) $(DEV_TSD_STATICROOT)
+ cp $(dist_static_DATA:%=$(srcdir)/%) $(DEV_TSD_STATICROOT)
+ find -L $(DEV_TSD_STATICROOT) -type l -delete
+ p=`pwd`/gwt/queryui && cd $(DEV_TSD_STATICROOT) \
+ && for i in $$p/*; do ln -s -f "$$i" || break; done
+ find -L $(DEV_TSD_STATICROOT)/gwt -type f | xargs touch
+ @touch .staticroot-stamp
+
+# Install all the files from the static dir into $staticdir.
+# Ideally I'd like Automake to take care of this, but right now I don't see
+# how to tell it to install a bunch of files recursively for which I don't
+# know ahead of time what the file names are.
+install-data-local: staticroot
+ @$(NORMAL_INSTALL)
+ test -z "$(staticdir)" || $(MKDIR_P) "$(DESTDIR)$(staticdir)"
+ @set -e; pwd; ls -lFh; cd "$(DEV_TSD_STATICROOT)"; \
+ list=`find -L . ! -type d`; for p in $$list; do \
+ p=$${p#./}; \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ dstdir=`dirname "$(DESTDIR)$(staticdir)/$$p"`; \
+ if test -d "$$dstdir"; then :; else \
+ echo " $(MKDIR_P) '$$dstdir'"; $(MKDIR_P) "$$dstdir"; fi; \
+ echo " $(dist_staticDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(staticdir)/$$p'"; \
+ $(dist_staticDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(staticdir)/$$p"; \
+ done
+
+uninstall-local:
+ @$(NORMAL_UNINSTALL)
+ rm -rf "$(DESTDIR)$(staticdir)"
+
+# I don't know why Automake leaves this directory behind.
+uninstall-hook:
+ test ! -d "$(pkgdatadir)" || rmdir "$(pkgdatadir)"
+
+get_runtime_dep_classpath := `echo $(test_DEPS) | tr ' ' ':'`
+$(test_classes): $(jar) $(test_SRC) $(test_DEPS)
+ $(JAVA_COMPILE) -cp $(get_runtime_dep_classpath) $(test_SRC:%=$(srcdir)/%)
+
+classes_with_nested_classes := $(classes:.class=*.class)
+test_classes_with_nested_classes := $(test_classes:.class=*.class)
+
+# Little set script to make a pretty-ish banner.
+BANNER := sed 's/^.*/ & /;h;s/./=/g;p;x;p;x'
+check-local: $(UNITTESTS)
+ classes=`cd $(builddir) && echo $(test_classes_with_nested_classes)` && \
+ success=: && cp="$(get_runtime_dep_classpath):$(builddir)" && \
+ for i in $$classes; do \
+ case $$i in (*[$$]*) continue;; esac; \
+ echo "Running tests for `basename $$i .class`" | $(BANNER); \
+ $(JAVA) -ea $(JVM_ARGS) -cp "$$cp" org.junit.runner.JUnitCore `echo $${i%.class} | tr / .` $(ARGS) || success=false; \
+ done && $$success
+
+git_version := \
+ `git rev-list --pretty=format:%h HEAD --max-count=1 | sed 1d || echo unknown`
+manifest: .javac-stamp .git/HEAD
+ { echo "Specification-Title: $(spec_title)"; \
+ echo "Specification-Version: $(PACKAGE_VERSION)"; \
+ echo "Specification-Vendor: $(spec_vendor)"; \
+ echo "Implementation-Title: $(package)"; \
+ echo "Implementation-Version: $(git_version)"; \
+ echo "Implementation-Vendor: $(spec_vendor)"; } >"$@"
+
+$(jar): manifest .javac-stamp $(classes)
+ $(JAR) cfm `basename $(jar)` manifest $(classes_with_nested_classes) \
+ || { rv=$$? && rm -f `basename $(jar)` && exit $$rv; }
+# ^^^^^^^^^^^^^^^^^^^^^^^
+# I've seen cases where `jar' exits with an error but leaves a partially built .jar file!
+
+JAVADOC_DIR = api
+doc: $(JAVADOC_DIR)/index.html
+
+JDK_JAVADOC = http://download.oracle.com/javase/6/docs/api
+NETTY_JAVADOC = http://docs.jboss.org/netty/3.2/api
+$(JAVADOC_DIR)/index.html: $(tsdb_SRC)
+ $(JAVADOC) -d $(JAVADOC_DIR) -classpath $(get_dep_classpath) \
+ -link $(JDK_JAVADOC) -link $(NETTY_JAVADOC) $(tsdb_SRC_srcdir)
+
+dist-hook:
+ $(MKDIR_P) $(distdir)/.git
+ echo $(git_version) >$(distdir)/.git/HEAD
+
+mostlyclean-local:
+ @rm -f .javac-stamp .gwtc-stamp* .staticroot-stamp
+ rm -rf gwt staticroot
+ rm -f manifest $(BUILT_SOURCES)
+ rm -f $(classes_with_nested_classes) $(test_classes_with_nested_classes)
+ test -d $(package_dir) || exit 0 \
+ && find $(package_dir) -depth -type d -exec rmdir {} ';' \
+ && dir=$(package_dir) && dir=$${dir%/*} \
+ && while test x"$$dir" != x"$${dir%/*}"; do \
+ rmdir "$$dir" && dir=$${dir%/*} || break; \
+ done \
+ && rmdir "$$dir"
+
+clean-local:
+ rm -f $(jar) tsdb
+ rm -rf $(JAVADOC_DIR)
+
+.PHONY: jar doc check gwtc gwtdev staticroot gwttsd
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000000..d77aa233e5
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,17 @@
+#!/bin/sh
+# Copyright (C) 2011 The OpenTSDB Authors.
+#
+# This library is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see .
+
+exec autoreconf -fvi
diff --git a/build-aux/.gitignore b/build-aux/.gitignore
new file mode 100644
index 0000000000..022060c726
--- /dev/null
+++ b/build-aux/.gitignore
@@ -0,0 +1,2 @@
+install-sh
+missing
diff --git a/buildtools/gen_build_data.sh b/build-aux/gen_build_data.sh
similarity index 100%
rename from buildtools/gen_build_data.sh
rename to build-aux/gen_build_data.sh
diff --git a/build-aux/tsdb.m4 b/build-aux/tsdb.m4
new file mode 100644
index 0000000000..38b4ab0f52
--- /dev/null
+++ b/build-aux/tsdb.m4
@@ -0,0 +1,24 @@
+# Copyright (C) 2011 The OpenTSDB Authors.
+#
+# This library is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see .
+
+# Like AC_PATH_PROGS but errors out if the program cannot be found.
+AC_DEFUN([TSDB_FIND_PROG],
+[m4_pushdef([TSD_PROGNAME], m4_toupper([$1]))dnl
+AC_PATH_PROGS(TSD_PROGNAME, [m4_default([$2], [$1])])
+test -z "$TSD_PROGNAME" && {
+ AC_MSG_ERROR([cannot find $1])
+}
+m4_popdef([TSD_PROGNAME])dnl
+])
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000000..646e377307
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+set -xe
+test -f configure || ./bootstrap
+test -d build || mkdir build
+cd build
+test -f Makefile || ../configure "$@"
+exec make "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000000..d4477019a5
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,34 @@
+# Copyright (C) 2011 The OpenTSDB Authors.
+#
+# This library is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see .
+
+AC_INIT([opentsdb], [1.0], [opentsdb@googlegroups.com])
+AC_CONFIG_AUX_DIR([build-aux])
+AM_INIT_AUTOMAKE([foreign])
+
+AC_CONFIG_FILES([
+ Makefile
+])
+
+TSDB_FIND_PROG([md5], [md5sum md5])
+TSDB_FIND_PROG([java])
+TSDB_FIND_PROG([javac])
+TSDB_FIND_PROG([jar])
+TSDB_FIND_PROG([gnuplot])
+AC_PATH_PROG([JAVADOC], [javadoc], [])
+AM_MISSING_PROG([JAVADOC], [javadoc])
+
+AC_SUBST([staticdir], ['${pkgdatadir}/static'])
+
+AC_OUTPUT
diff --git a/src/.gitignore b/src/.gitignore
index d6a2043c5b..afdf436952 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,2 +1 @@
BuildData.java
-tsdb.local
diff --git a/src/graph/mygnuplot.sh b/src/mygnuplot.sh
similarity index 100%
rename from src/graph/mygnuplot.sh
rename to src/mygnuplot.sh
diff --git a/src/tsd/GraphHandler.java b/src/tsd/GraphHandler.java
index bf79dd2718..cba8f3af4c 100644
--- a/src/tsd/GraphHandler.java
+++ b/src/tsd/GraphHandler.java
@@ -18,6 +18,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -696,10 +697,8 @@ static int runGnuplot(final HttpQuery query,
final Plot plot) throws IOException {
final int nplotted = plot.dumpToFiles(basepath);
final long start_time = System.nanoTime();
- final Process gnuplot = new ProcessBuilder(
- // XXX Java Kludge XXX
- "./src/graph/mygnuplot.sh", basepath + ".out", basepath + ".err",
- basepath + ".gnuplot").start();
+ final Process gnuplot = new ProcessBuilder(GNUPLOT,
+ basepath + ".out", basepath + ".err", basepath + ".gnuplot").start();
final int rv;
try {
rv = gnuplot.waitFor(); // Couldn't find how to do this asynchronously.
@@ -967,6 +966,42 @@ public Thread newThread(final Runnable r) {
}
}
+ /** Name of the wrapper script we use to execute Gnuplot. */
+ private static final String WRAPPER = "mygnuplot.sh";
+ /** Path to the wrapper script. */
+ private static final String GNUPLOT;
+ static {
+ GNUPLOT = findGnuplotHelperScript();
+ }
+
+ /**
+ * Iterate through the class path and look for the Gnuplot helper script.
+ * @return The path to the wrapper script.
+ */
+ private static String findGnuplotHelperScript() {
+ final URL url = GraphHandler.class.getClassLoader().getResource(WRAPPER);
+ if (url == null) {
+ throw new RuntimeException("Couldn't find " + WRAPPER + " on the"
+ + " CLASSPATH: " + System.getProperty("java.class.path"));
+ }
+ final String path = url.getFile();
+ LOG.debug("Using Gnuplot wrapper at {}", path);
+ final File file = new File(path);
+ final String error;
+ if (!file.exists()) {
+ error = "non-existent";
+ } else if (!file.canExecute()) {
+ error = "non-executable";
+ } else if (!file.canRead()) {
+ error = "unreadable";
+ } else {
+ return path;
+ }
+ throw new RuntimeException("The " + WRAPPER + " found on the"
+ + " CLASSPATH (" + path + ") is a " + error + " file... WTF?"
+ + " CLASSPATH=" + System.getProperty("java.class.path"));
+ }
+
// ---------------- //
// Logging helpers. //
// ---------------- //
diff --git a/src/tsdb b/src/tsdb
deleted file mode 100755
index 3983024e12..0000000000
--- a/src/tsdb
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/bash
-
-set -e
-me=${0##*/}
-mydir=`dirname "$0"`
-for make in $MAKE make gmake; do
- # Try to weed out BSD make and such (they don't support those flags).
- $make --version --quiet >/dev/null 2>&1 && break
-done
-# TODO(tsuna): This is an ugly hack. The TSD needs to execute
-# src/graph/mygnuplot.sh and does so with a relative path to keep things
-# simpler. So we need to `cd' in the right directory... This means that
-# relative paths can't be given in argument to any of the commands. XXX
-cd "$mydir/.."
-# TODO(tsuna): This is an ugly hack (sigh). First of all, `printcp' leaves
-# a trailing colon at the end of the classpath it prints. We append `src'
-# because that's where logback.xml is and it needs to be on the classpath
-# for logback-core to find it (not the file itself but the directory
-# containing it...)
-CLASSPATH=`$make --quiet printcp`src || {
- echo >&2 "$make returned $?"
- echo >&2 'Please make sure you have GNU make installed in your PATH'
- exit 42
-}
-
-usage() {
- echo >&2 "usage: $me [args]"
- echo 'Valid commands: fsck, import, mkmetric, query, tsd, scan, uid'
- exit 1
-}
-
-case $1 in
- (fsck)
- MAINCLASS=Fsck
- ;;
- (import)
- MAINCLASS=TextImporter
- ;;
- (mkmetric)
- shift
- set uid assign metrics "$@"
- MAINCLASS=UidManager
- ;;
- (query)
- MAINCLASS=CliQuery
- ;;
- (tsd)
- MAINCLASS=TSDMain
- ;;
- (scan)
- MAINCLASS=DumpSeries
- ;;
- (uid)
- MAINCLASS=UidManager
- ;;
- (*)
- echo >&2 "$me: error: unknown command '$1'"
- usage
- ;;
-esac
-shift
-
-JAVA=${JAVA-'java'}
-JVMARGS=${JVMARGS-'-enableassertions -enablesystemassertions'}
-test -r "$mydir/tsdb.local" && . "$mydir/tsdb.local"
-exec $JAVA $JVMARGS -classpath "$CLASSPATH" net.opentsdb.tools.$MAINCLASS "$@"
diff --git a/tsdb.in b/tsdb.in
new file mode 100644
index 0000000000..4f8e858e2e
--- /dev/null
+++ b/tsdb.in
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+set -e
+me=${0##*/}
+mydir=`dirname "$0"`
+# Either:
+# abs_srcdir and abs_builddir are set: we're running in a dev tree
+# or pkgdatadir is set: we've been installed, we respect that.
+abs_srcdir=@abs_srcdir@
+abs_builddir=@abs_builddir@
+pkgdatadir=@pkgdatadir@
+# Either we've been installed and pkgdatadir exists, or we haven't been
+# installed and abs_srcdir / abs_builddir aren't empty.
+test -d "$pkgdatadir" || test -n "$abs_srcdir$abs_builddir" || {
+ echo >&2 "$me: Uh-oh, \`$pkgdatadir' doesn't exist, is OpenTSDB properly installed?"
+ exit 1
+}
+
+if test -n "$pkgdatadir"; then
+ localdir="$pkgdatadir"
+ for jar in "$pkgdatadir"/*.jar; do
+ CLASSPATH="$CLASSPATH:$jar"
+ done
+ # Add pkgdatadir itself so we can find logback.xml
+ CLASSPATH="$CLASSPATH:$pkgdatadir"
+else
+ localdir="$abs_builddir"
+ for jar in "$abs_builddir"/third_party/*/*.jar \
+ "$abs_srcdir"/third_party/*/*.jar \
+ "$abs_builddir"/*.jar; do
+ test -f "$jar" && CLASSPATH="$CLASSPATH:$jar"
+ done
+ # Add the src dir so we can find logback.xml
+ CLASSPATH="$CLASSPATH:$abs_srcdir/src"
+fi
+# Remove any leading colon.
+CLASSPATH="${CLASSPATH#:}"
+
+usage() {
+ echo >&2 "usage: $me [args]"
+ echo 'Valid commands: fsck, import, mkmetric, query, tsd, scan, uid'
+ exit 1
+}
+
+case $1 in
+ (fsck)
+ MAINCLASS=Fsck
+ ;;
+ (import)
+ MAINCLASS=TextImporter
+ ;;
+ (mkmetric)
+ shift
+ set uid assign metrics "$@"
+ MAINCLASS=UidManager
+ ;;
+ (query)
+ MAINCLASS=CliQuery
+ ;;
+ (tsd)
+ MAINCLASS=TSDMain
+ ;;
+ (scan)
+ MAINCLASS=DumpSeries
+ ;;
+ (uid)
+ MAINCLASS=UidManager
+ ;;
+ (*)
+ echo >&2 "$me: error: unknown command '$1'"
+ usage
+ ;;
+esac
+shift
+
+JAVA=${JAVA-'java'}
+JVMARGS=${JVMARGS-'-enableassertions -enablesystemassertions'}
+test -r "$localdir/tsdb.local" && . "$localdir/tsdb.local"
+exec $JAVA $JVMARGS -classpath "$CLASSPATH" net.opentsdb.tools.$MAINCLASS "$@"