Repository: incubator-htrace Updated Branches: refs/heads/master 10e0bc2cf -> a7ad113a1
HTRACE-28. htraced: add web UI directory (cmccabe) Project: http://git-wip-us.apache.org/repos/asf/incubator-htrace/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-htrace/commit/a7ad113a Tree: http://git-wip-us.apache.org/repos/asf/incubator-htrace/tree/a7ad113a Diff: http://git-wip-us.apache.org/repos/asf/incubator-htrace/diff/a7ad113a Branch: refs/heads/master Commit: a7ad113a1eb2ca746380faee04419c0c32e0eb6a Parents: 10e0bc2 Author: Colin P. Mccabe <[email protected]> Authored: Mon Dec 29 15:05:50 2014 -0800 Committer: Colin P. Mccabe <[email protected]> Committed: Tue Dec 30 11:29:00 2014 -0800 ---------------------------------------------------------------------- .gitignore | 1 + htrace-core/src/go/gobuild.sh | 5 + .../go/src/org/apache/htrace/bundler/bundler.go | 207 +++++++++++++++++++ .../go/src/org/apache/htrace/htraced/rest.go | 16 ++ .../src/org/apache/htrace/resource/catalog.go | 29 +++ htrace-core/src/web/index.html | 6 + 6 files changed, 264 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a7ad113a/.gitignore ---------------------------------------------------------------------- diff --git a/.gitignore b/.gitignore index 58aa24d..f9788be 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ dependency-reduced-pom.xml htrace-core/src/go/bin htrace-core/src/go/pkg +htrace-core/src/go/src/org/apache/htrace/resource http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a7ad113a/htrace-core/src/go/gobuild.sh ---------------------------------------------------------------------- diff --git a/htrace-core/src/go/gobuild.sh b/htrace-core/src/go/gobuild.sh index c689dac..d8a6b47 100755 --- a/htrace-core/src/go/gobuild.sh +++ b/htrace-core/src/go/gobuild.sh @@ -80,4 +80,9 @@ if [ -n "${ldconfig}" ]; then fi fi +if [ "$ACTION" == "get" ]; then + go run "$SCRIPT_DIR/src/org/apache/htrace/bundler/bundler.go" \ + --src="$SCRIPT_DIR/../web/" --dst="$SCRIPT_DIR/src/org/apache/htrace/resource/" \ + || die "bundler failed" +fi go "${ACTION}" -v org/apache/htrace/... "$@" http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a7ad113a/htrace-core/src/go/src/org/apache/htrace/bundler/bundler.go ---------------------------------------------------------------------- diff --git a/htrace-core/src/go/src/org/apache/htrace/bundler/bundler.go b/htrace-core/src/go/src/org/apache/htrace/bundler/bundler.go new file mode 100644 index 0000000..7e6f542 --- /dev/null +++ b/htrace-core/src/go/src/org/apache/htrace/bundler/bundler.go @@ -0,0 +1,207 @@ +/* + * 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 main + +// +// The bundler turns files into resources contained in go code. +// +// This is useful for serving HTML and Javascript files from a self-contained binary. +// + +import ( + "bufio" + "fmt" + "gopkg.in/alecthomas/kingpin.v1" + "io/ioutil" + "log" + "os" + "strings" +) + +const APACHE_HEADER = `/* + * 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. + */ +` + +const GENERATED_CODE_COMMENT = "// THIS IS GENERATED CODE. DO NOT EDIT." + +// Return true if a file contains a given string. +func fileContainsString(path, line string) (bool, error) { + file, err := os.Open(path) + if err != nil { + return false, err + } + defer file.Close() + scanner := bufio.NewScanner(file) + for scanner.Scan() { + if strings.Contains(scanner.Text(), line) { + return true, nil + } + } + if err := scanner.Err(); err != nil { + return false, err + } + return false, nil +} + +// Delete generated files that are in dfiles but not sfiles. +// sfiles and dfiles must be sorted by file name. +func deleteUnusedDst(sfiles []os.FileInfo, dst string, dfiles []os.FileInfo) error { + s := 0 + for d := range dfiles { + fullDst := dst + string(os.PathSeparator) + dfiles[d].Name() + generated, err := fileContainsString(fullDst, GENERATED_CODE_COMMENT) + if err != nil { + return err + } + if !generated { + // Skip this destination file, since it is not generated. + continue + } + found := false + for { + if s >= len(sfiles) { + break + } + if sfiles[s].Name()+".go" == dfiles[d].Name() { + found = true + break + } + if sfiles[s].Name()+".go" > dfiles[d].Name() { + break + } + s++ + } + if !found { + log.Printf("Removing %s\n", fullDst) + err := os.Remove(fullDst) + if err != nil { + return err + } + } + } + return nil +} + +func stripSuffixes(str string) string { + idx := strings.Index(str, ".") + if idx < 0 { + return str + } + return str[0:idx] +} + +func createBundleFile(pkg, src, sfile, tdir string) error { + // Open destination file and write header. + fullDst := tdir + string(os.PathSeparator) + sfile + ".go" + out, err := os.Create(fullDst) + if err != nil { + return err + } + defer out.Close() + _, err = out.WriteString(APACHE_HEADER) + if err != nil { + return err + } + _, err = out.WriteString("\n" + GENERATED_CODE_COMMENT + "\n") + if err != nil { + return err + } + _, err = out.WriteString(fmt.Sprintf("\npackage %s\n", pkg)) + if err != nil { + return err + } + _, err = out.WriteString(fmt.Sprintf("var _ = addResource(\"/%s\", `\n", stripSuffixes(sfile))) + if err != nil { + return err + } + + // Open source file and create scanner. + fullSrc := src + string(os.PathSeparator) + sfile + in, err := os.Open(fullSrc) + if err != nil { + return err + } + defer in.Close() + reader := bufio.NewReader(in) + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + _, err := out.WriteString(strings.Replace(scanner.Text(), "`", "` + \"`\" + `", -1) + "\n") + if err != nil { + return err + } + } + _, err = out.WriteString("`)\n") + if err != nil { + return err + } + err = out.Close() + if err != nil { + return err + } + return nil +} + +func main() { + app := kingpin.New("bundler", "The HTrace resource bundling build utility.") + src := app.Flag("src", "Source path for bundled resources.").Default("").String() + dst := app.Flag("dst", "Destination path for bundled resources.").Default("").String() + pkg := app.Flag("pkg", "Package name to use for bundled resources.").Default("resource").String() + kingpin.MustParse(app.Parse(os.Args[1:])) + if *src == "" { + log.Fatal("You must supply a src directory to bundle.") + } + if *dst == "" { + log.Fatal("You must supply a dst directory for output.") + } + sfiles, err := ioutil.ReadDir(*src) + if err != nil { + log.Fatal("Error listing files in src directory %s: %s\n", *src, err.Error()) + } + var dfiles []os.FileInfo + dfiles, err = ioutil.ReadDir(*dst) + if err != nil { + log.Fatal("Error listing files in output directory %s: %s\n", *dst, err.Error()) + } + deleteUnusedDst(sfiles, *dst, dfiles) + for s := range sfiles { + err = createBundleFile(*pkg, *src, sfiles[s].Name(), *dst) + if err != nil { + log.Fatal("Error creating bundle file for %s in %s: %s\n", + sfiles[s], *dst, err.Error()) + } + log.Printf("Bundled %s\n", *dst+string(os.PathSeparator)+sfiles[s].Name()) + } +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a7ad113a/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go ---------------------------------------------------------------------- diff --git a/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go b/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go index 8374c40..f0bb2c1 100644 --- a/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go +++ b/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go @@ -25,6 +25,7 @@ import ( "net/http" "org/apache/htrace/common" "org/apache/htrace/conf" + "org/apache/htrace/resource" "strconv" ) @@ -125,6 +126,18 @@ func (hand *findChildrenHandler) ServeHTTP(w http.ResponseWriter, req *http.Requ w.Write(jbytes) } +type defaultServeHandler struct { +} + +func (hand *defaultServeHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + rsc := resource.Catalog[req.URL.Path] + if rsc == "" { + w.WriteHeader(http.StatusNotFound) + return + } + w.Write([]byte(rsc)) +} + func startRestServer(cnf *conf.Config, store *dataStore) { mux := http.NewServeMux() @@ -137,6 +150,9 @@ func startRestServer(cnf *conf.Config, store *dataStore) { findChildrenH := &findChildrenHandler{dataStoreHandler: dataStoreHandler{store: store}} mux.Handle("/findChildren", findChildrenH) + defaultServeH := &defaultServeHandler{} + mux.Handle("/", defaultServeH) + http.ListenAndServe(cnf.Get(conf.HTRACE_WEB_ADDRESS), mux) log.Println("Started REST server...") } http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a7ad113a/htrace-core/src/go/src/org/apache/htrace/resource/catalog.go ---------------------------------------------------------------------- diff --git a/htrace-core/src/go/src/org/apache/htrace/resource/catalog.go b/htrace-core/src/go/src/org/apache/htrace/resource/catalog.go new file mode 100644 index 0000000..5b71f88 --- /dev/null +++ b/htrace-core/src/go/src/org/apache/htrace/resource/catalog.go @@ -0,0 +1,29 @@ +/* + * 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 resource + +// Map containing all resources. +var Catalog map[string]string = make(map[string]string) + +// Function called by generated code to add a resource to the catalog. +func addResource(key, val string) string { + Catalog[key] = val + return key +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a7ad113a/htrace-core/src/web/index.html ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/index.html b/htrace-core/src/web/index.html new file mode 100644 index 0000000..fb49055 --- /dev/null +++ b/htrace-core/src/web/index.html @@ -0,0 +1,6 @@ +<html> +<body> +<head><title>HTRACE</title></head> +Hello, world.<p/> +</body> +</html>
