You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by mi...@apache.org on 2016/11/07 22:23:42 UTC

[21/26] incubator-trafficcontrol git commit: merge master

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/config/config.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/config/config.go b/traffic_monitor/experimental/traffic_monitor/config/config.go
index 1ca4b80..ce24883 100644
--- a/traffic_monitor/experimental/traffic_monitor/config/config.go
+++ b/traffic_monitor/experimental/traffic_monitor/config/config.go
@@ -1,22 +1,49 @@
 package config
 
+/*
+ * 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.
+ */
+
+
 import (
 	"encoding/json"
 	"io/ioutil"
 	"time"
 )
 
+// LogLocation is a location to log to. This may be stdout, stderr, null (/dev/null), or a valid file path.
 type LogLocation string
 
-const LogLocationStdout = "stdout"
-const LogLocationStderr = "stderr"
-const LogLocationNull = "null"
+const (
+	// LogLocationStdout indicates the stdout IO stream
+	LogLocationStdout = "stdout"
+	// LogLocationStderr indicates the stderr IO stream
+	LogLocationStderr = "stderr"
+	// LogLocationNull indicates the null IO stream (/dev/null)
+	LogLocationNull = "null"
+)
 
+// Config is the configuration for the application. It includes myriad data, such as polling intervals and log locations.
 type Config struct {
 	CacheHealthPollingInterval   time.Duration `json:"-"`
 	CacheStatPollingInterval     time.Duration `json:"-"`
 	MonitorConfigPollingInterval time.Duration `json:"-"`
-	HttpTimeout                  time.Duration `json:"-"`
+	HTTPTimeout                  time.Duration `json:"-"`
 	PeerPollingInterval          time.Duration `json:"-"`
 	MaxEvents                    uint64        `json:"max_events"`
 	MaxStatHistory               uint64        `json:"max_stat_history"`
@@ -27,13 +54,17 @@ type Config struct {
 	LogLocationWarning           string        `json:"log_location_warning"`
 	LogLocationInfo              string        `json:"log_location_info"`
 	LogLocationDebug             string        `json:"log_location_debug"`
+	ServeReadTimeout             time.Duration `json:"-"`
+	ServeWriteTimeout            time.Duration `json:"-"`
+	HealthToStatRatio            uint64        `json:"health_to_stat_ratio"`
 }
 
+// DefaultConfig is the default configuration for the application, if no configuration file is given, or if a given config setting doesn't exist in the config file.
 var DefaultConfig = Config{
 	CacheHealthPollingInterval:   6 * time.Second,
 	CacheStatPollingInterval:     6 * time.Second,
 	MonitorConfigPollingInterval: 5 * time.Second,
-	HttpTimeout:                  2 * time.Second,
+	HTTPTimeout:                  2 * time.Second,
 	PeerPollingInterval:          5 * time.Second,
 	MaxEvents:                    200,
 	MaxStatHistory:               5,
@@ -44,6 +75,9 @@ var DefaultConfig = Config{
 	LogLocationWarning:           LogLocationStdout,
 	LogLocationInfo:              LogLocationNull,
 	LogLocationDebug:             LogLocationNull,
+	ServeReadTimeout:             10 * time.Second,
+	ServeWriteTimeout:            10 * time.Second,
+	HealthToStatRatio:            4,
 }
 
 // MarshalJSON marshals custom millisecond durations. Aliasing inspired by http://choly.ca/post/go-json-marshalling/
@@ -53,16 +87,18 @@ func (c *Config) MarshalJSON() ([]byte, error) {
 		CacheHealthPollingIntervalMs   uint64 `json:"cache_health_polling_interval_ms"`
 		CacheStatPollingIntervalMs     uint64 `json:"cache_stat_polling_interval_ms"`
 		MonitorConfigPollingIntervalMs uint64 `json:"monitor_config_polling_interval_ms"`
-		HttpTimeoutMs                  uint64 `json:"http_timeout_ms"`
+		HTTPTimeoutMS                  uint64 `json:"http_timeout_ms"`
 		PeerPollingIntervalMs          uint64 `json:"peer_polling_interval_ms"`
 		HealthFlushIntervalMs          uint64 `json:"health_flush_interval_ms"`
 		StatFlushIntervalMs            uint64 `json:"stat_flush_interval_ms"`
+		ServeReadTimeoutMs             uint64 `json:"serve_read_timeout_ms"`
+		ServeWriteTimeoutMs            uint64 `json:"serve_write_timeout_ms"`
 		*Alias
 	}{
 		CacheHealthPollingIntervalMs:   uint64(c.CacheHealthPollingInterval / time.Millisecond),
 		CacheStatPollingIntervalMs:     uint64(c.CacheStatPollingInterval / time.Millisecond),
 		MonitorConfigPollingIntervalMs: uint64(c.MonitorConfigPollingInterval / time.Millisecond),
-		HttpTimeoutMs:                  uint64(c.HttpTimeout / time.Millisecond),
+		HTTPTimeoutMS:                  uint64(c.HTTPTimeout / time.Millisecond),
 		PeerPollingIntervalMs:          uint64(c.PeerPollingInterval / time.Millisecond),
 		HealthFlushIntervalMs:          uint64(c.HealthFlushInterval / time.Millisecond),
 		StatFlushIntervalMs:            uint64(c.StatFlushInterval / time.Millisecond),
@@ -70,16 +106,19 @@ func (c *Config) MarshalJSON() ([]byte, error) {
 	})
 }
 
+// UnmarshalJSON populates this config object from given JSON bytes.
 func (c *Config) UnmarshalJSON(data []byte) error {
 	type Alias Config
 	aux := &struct {
 		CacheHealthPollingIntervalMs   *uint64 `json:"cache_health_polling_interval_ms"`
 		CacheStatPollingIntervalMs     *uint64 `json:"cache_stat_polling_interval_ms"`
 		MonitorConfigPollingIntervalMs *uint64 `json:"monitor_config_polling_interval_ms"`
-		HttpTimeoutMs                  *uint64 `json:"http_timeout_ms"`
+		HTTPTimeoutMS                  *uint64 `json:"http_timeout_ms"`
 		PeerPollingIntervalMs          *uint64 `json:"peer_polling_interval_ms"`
 		HealthFlushIntervalMs          *uint64 `json:"health_flush_interval_ms"`
 		StatFlushIntervalMs            *uint64 `json:"stat_flush_interval_ms"`
+		ServeReadTimeoutMs             *uint64 `json:"serve_read_timeout_ms"`
+		ServeWriteTimeoutMs            *uint64 `json:"serve_write_timeout_ms"`
 		*Alias
 	}{
 		Alias: (*Alias)(c),
@@ -97,8 +136,8 @@ func (c *Config) UnmarshalJSON(data []byte) error {
 	if aux.MonitorConfigPollingIntervalMs != nil {
 		c.MonitorConfigPollingInterval = time.Duration(*aux.MonitorConfigPollingIntervalMs) * time.Millisecond
 	}
-	if aux.HttpTimeoutMs != nil {
-		c.HttpTimeout = time.Duration(*aux.HttpTimeoutMs) * time.Millisecond
+	if aux.HTTPTimeoutMS != nil {
+		c.HTTPTimeout = time.Duration(*aux.HTTPTimeoutMS) * time.Millisecond
 	}
 	if aux.PeerPollingIntervalMs != nil {
 		c.PeerPollingInterval = time.Duration(*aux.PeerPollingIntervalMs) * time.Millisecond
@@ -109,6 +148,12 @@ func (c *Config) UnmarshalJSON(data []byte) error {
 	if aux.StatFlushIntervalMs != nil {
 		c.StatFlushInterval = time.Duration(*aux.StatFlushIntervalMs) * time.Millisecond
 	}
+	if aux.ServeReadTimeoutMs != nil {
+		c.ServeReadTimeout = time.Duration(*aux.ServeReadTimeoutMs) * time.Millisecond
+	}
+	if aux.ServeWriteTimeoutMs != nil {
+		c.ServeWriteTimeout = time.Duration(*aux.ServeWriteTimeoutMs) * time.Millisecond
+	}
 	return nil
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/deliveryservice/stat.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/deliveryservice/stat.go b/traffic_monitor/experimental/traffic_monitor/deliveryservice/stat.go
index 8b72163..ebd883f 100644
--- a/traffic_monitor/experimental/traffic_monitor/deliveryservice/stat.go
+++ b/traffic_monitor/experimental/traffic_monitor/deliveryservice/stat.go
@@ -1,14 +1,34 @@
 package deliveryservice
 
+/*
+ * 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.
+ */
+
+
 import (
 	"fmt"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/common/log"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/cache"
-	dsdata "github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/deliveryservicedata"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/enum"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/http_server"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/peer"
-	todata "github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/trafficopsdata"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/common/log"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/cache"
+	dsdata "github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/deliveryservicedata"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/enum"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/peer"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/srvhttp"
+	todata "github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/trafficopsdata"
 	"net/url"
 	"strconv"
 	"time"
@@ -16,24 +36,30 @@ import (
 
 // TODO remove 'ds' and 'stat' from names
 
+// Stats is the JSON-serialisable representation of delivery service Stats. It maps delivery service names to individual stat objects.
 // TODO remove DeliveryService and set type to the map directly, or add other members
 type Stats struct {
 	DeliveryService map[enum.DeliveryServiceName]dsdata.Stat `json:"deliveryService"`
+	Time            time.Time                                `json:"-"`
 }
 
-func (a Stats) Copy() Stats {
+// Copy performs a deep copy of this Stats object.
+func (s Stats) Copy() Stats {
 	b := NewStats()
-	for k, v := range a.DeliveryService {
+	for k, v := range s.DeliveryService {
 		b.DeliveryService[k] = v.Copy()
 	}
+	b.Time = s.Time
 	return b
 }
 
-func (a Stats) Get(name enum.DeliveryServiceName) (dsdata.StatReadonly, bool) {
-	ds, ok := a.DeliveryService[name]
+// Get returns the stats for the given delivery service, and whether it exists.
+func (s Stats) Get(name enum.DeliveryServiceName) (dsdata.StatReadonly, bool) {
+	ds, ok := s.DeliveryService[name]
 	return ds, ok
 }
 
+// NewStats creates a new Stats object, initializing any pointer members.
 // TODO rename to just 'New'?
 func NewStats() Stats {
 	return Stats{DeliveryService: map[enum.DeliveryServiceName]dsdata.Stat{}}
@@ -59,7 +85,7 @@ func addAvailableData(dsStats Stats, crStates peer.Crstates, serverCachegroups m
 			log.Warnf("CreateStats not adding availability data for '%s': not found in DeliveryServices\n", cache)
 			continue
 		}
-		cacheType, ok := serverTypes[enum.CacheName(cache)]
+		cacheType, ok := serverTypes[cache]
 		if !ok {
 			log.Warnf("CreateStats not adding availability data for '%s': not found in Server Types\n", cache)
 			continue
@@ -71,19 +97,20 @@ func addAvailableData(dsStats Stats, crStates peer.Crstates, serverCachegroups m
 				continue
 			}
 
-			stat, ok := dsStats.DeliveryService[enum.DeliveryServiceName(deliveryService)]
+			stat, ok := dsStats.DeliveryService[deliveryService]
 			if !ok {
 				log.Warnf("CreateStats not adding availability data for '%s': not found in Stats\n", cache)
 				continue // TODO log warning? Error?
 			}
 
 			if available.IsAvailable {
-				// c.IsAvailable.Value
 				stat.CommonStats.IsAvailable.Value = true
+				// TODO fix to be whether the Delivery Service has exceeded max kbps defined in Traffic Ops in `/health/cdn-name`?
+				stat.CommonStats.IsHealthy.Value = true
 				stat.CommonStats.CachesAvailableNum.Value++
-				cacheGroupStats := stat.CacheGroups[enum.CacheGroupName(cacheGroup)]
+				cacheGroupStats := stat.CacheGroups[cacheGroup]
 				cacheGroupStats.IsAvailable.Value = true
-				stat.CacheGroups[enum.CacheGroupName(cacheGroup)] = cacheGroupStats
+				stat.CacheGroups[cacheGroup] = cacheGroupStats
 				stat.TotalStats.IsAvailable.Value = true
 				typeStats := stat.Types[cacheType]
 				typeStats.IsAvailable.Value = true
@@ -91,13 +118,13 @@ func addAvailableData(dsStats Stats, crStates peer.Crstates, serverCachegroups m
 			}
 
 			// TODO fix nested ifs
-			if results, ok := statHistory[enum.CacheName(cache)]; ok {
+			if results, ok := statHistory[cache]; ok {
 				if len(results) < 1 {
 					log.Warnf("no results %v %v\n", cache, deliveryService)
 				} else {
 					result := results[0]
 					if result.PrecomputedData.Reporting {
-						stat.CommonStats.CachesReporting[enum.CacheName(cache)] = true
+						stat.CommonStats.CachesReporting[cache] = true
 					} else {
 						log.Debugf("no reporting %v %v\n", cache, deliveryService)
 					}
@@ -106,7 +133,7 @@ func addAvailableData(dsStats Stats, crStates peer.Crstates, serverCachegroups m
 				log.Debugf("no result for %v %v\n", cache, deliveryService)
 			}
 
-			dsStats.DeliveryService[enum.DeliveryServiceName(deliveryService)] = stat // TODO Necessary? Remove?
+			dsStats.DeliveryService[deliveryService] = stat // TODO Necessary? Remove?
 		}
 	}
 	return dsStats, nil
@@ -118,10 +145,12 @@ type LastStats struct {
 	Caches           map[enum.CacheName]LastStatsData
 }
 
+// NewLastStats returns a new LastStats object, initializing internal pointer values.
 func NewLastStats() LastStats {
 	return LastStats{DeliveryServices: map[enum.DeliveryServiceName]LastDSStat{}, Caches: map[enum.CacheName]LastStatsData{}}
 }
 
+// Copy performs a deep copy of this LastStats object.
 func (a LastStats) Copy() LastStats {
 	b := NewLastStats()
 	for k, v := range a.DeliveryServices {
@@ -133,6 +162,7 @@ func (a LastStats) Copy() LastStats {
 	return b
 }
 
+// LastDSStat maps and aggregates the last stats received for the given delivery service to caches, cache groups, types, and total.
 // TODO figure a way to associate this type with StatHTTP, with which its members correspond.
 type LastDSStat struct {
 	Caches      map[enum.CacheName]LastStatsData
@@ -141,6 +171,7 @@ type LastDSStat struct {
 	Total       LastStatsData
 }
 
+// Copy performs a deep copy of this LastDSStat object.
 func (a LastDSStat) Copy() LastDSStat {
 	b := LastDSStat{
 		CacheGroups: map[enum.CacheGroupName]LastStatsData{},
@@ -168,6 +199,7 @@ func newLastDSStat() LastDSStat {
 	}
 }
 
+// LastStatsData contains the last stats and per-second calculations for bytes and status codes received from a cache.
 type LastStatsData struct {
 	Bytes     LastStatData
 	Status2xx LastStatData
@@ -187,6 +219,7 @@ func (a LastStatsData) Sum(b LastStatsData) LastStatsData {
 	}
 }
 
+// LastStatData contains the value, time it was received, and per-second calculation since the previous stat, for a stat from a cache.
 type LastStatData struct {
 	PerSec float64
 	Stat   int64
@@ -201,6 +234,7 @@ func (a LastStatData) Sum(b LastStatData) LastStatData {
 	}
 }
 
+// BytesPerKilobit is the number of bytes in a kilobit.
 const BytesPerKilobit = 125
 
 func addLastStat(lastData LastStatData, newStat int64, newStatTime time.Time) (LastStatData, error) {
@@ -298,7 +332,7 @@ func addDSPerSecStats(dsName enum.DeliveryServiceName, stat dsdata.Stat, lastSta
 	for cacheName, cacheStats := range stat.Caches {
 		lastStat.Caches[cacheName], err = addLastStats(lastStat.Caches[cacheName], cacheStats, dsStatsTime)
 		if err != nil {
-			log.Errorf("debugq %v Error adding kbps for cache %v: %v", cacheName, err)
+			log.Errorf("%v adding kbps for cache %v: %v", dsName, cacheName, err)
 			continue
 		}
 		cacheStats.Kbps.Value = lastStat.Caches[cacheName].Bytes.PerSec / BytesPerKilobit
@@ -371,15 +405,16 @@ func addPerSecStats(statHistory map[enum.CacheName][]cache.Result, dsStats Stats
 	return dsStats, lastStats
 }
 
+// CreateStats aggregates and creates statistics from given stat history. It returns the created stats, information about these stats necessary for the next calculation, and any error.
 func CreateStats(statHistory map[enum.CacheName][]cache.Result, toData todata.TOData, crStates peer.Crstates, lastStats LastStats, now time.Time) (Stats, LastStats, error) {
 	start := time.Now()
 	dsStats := NewStats()
-	for deliveryService, _ := range toData.DeliveryServiceServers {
+	for deliveryService := range toData.DeliveryServiceServers {
 		if deliveryService == "" {
 			log.Errorf("EMPTY CreateStats deliveryService")
 			continue
 		}
-		dsStats.DeliveryService[enum.DeliveryServiceName(deliveryService)] = *dsdata.NewStat()
+		dsStats.DeliveryService[deliveryService] = *dsdata.NewStat()
 	}
 	dsStats = setStaticData(dsStats, toData.DeliveryServiceServers)
 	var err error
@@ -397,7 +432,7 @@ func CreateStats(statHistory map[enum.CacheName][]cache.Result, toData todata.TO
 			log.Warnf("server %s has no cachegroup, skipping\n", server)
 			continue
 		}
-		serverType, ok := toData.ServerTypes[enum.CacheName(server)]
+		serverType, ok := toData.ServerTypes[server]
 		if !ok {
 			log.Warnf("server %s not in CRConfig, skipping\n", server)
 			continue
@@ -428,13 +463,20 @@ func CreateStats(statHistory map[enum.CacheName][]cache.Result, toData todata.TO
 
 	perSecStats, lastStats := addPerSecStats(statHistory, dsStats, lastStats, now, toData.ServerCachegroups, toData.ServerTypes)
 	log.Infof("CreateStats took %v\n", time.Since(start))
+	perSecStats.Time = time.Now()
 	return perSecStats, lastStats, nil
 }
 
 func addStatCacheStats(s *dsdata.StatsOld, c dsdata.StatCacheStats, deliveryService enum.DeliveryServiceName, prefix string, t int64, filter dsdata.Filter) *dsdata.StatsOld {
 	add := func(name, val string) {
 		if filter.UseStat(name) {
-			s.DeliveryService[deliveryService][dsdata.StatName(prefix+name)] = []dsdata.StatOld{dsdata.StatOld{Time: t, Value: val}}
+			// This is for compatibility with the Traffic Monitor 1.0 API.
+			// TODO abstract this? Or deprecate and remove it?
+			if name == "isAvailable" || name == "error-string" {
+				s.DeliveryService[deliveryService][dsdata.StatName("location."+prefix+name)] = []dsdata.StatOld{dsdata.StatOld{Time: t, Value: val}}
+			} else {
+				s.DeliveryService[deliveryService][dsdata.StatName(prefix+name)] = []dsdata.StatOld{dsdata.StatOld{Time: t, Value: val}}
+			}
 		}
 	}
 	add("out_bytes", strconv.Itoa(int(c.OutBytes.Value)))
@@ -449,7 +491,7 @@ func addStatCacheStats(s *dsdata.StatsOld, c dsdata.StatCacheStats, deliveryServ
 	add("tps_4xx", fmt.Sprintf("%f", c.Tps4xx.Value))
 	add("tps_3xx", fmt.Sprintf("%f", c.Tps3xx.Value))
 	add("tps_2xx", fmt.Sprintf("%f", c.Tps2xx.Value))
-	add("error", c.ErrorString.Value)
+	add("error-string", c.ErrorString.Value)
 	add("tps_total", strconv.Itoa(int(c.TpsTotal.Value)))
 	return s
 }
@@ -470,16 +512,16 @@ func addCommonData(s *dsdata.StatsOld, c *dsdata.StatCommon, deliveryService enu
 	return s
 }
 
-// StatsJSON returns an object formatted as expected to be serialized to JSON and served.
-func (dsStats Stats) JSON(filter dsdata.Filter, params url.Values) dsdata.StatsOld {
-	now := time.Now().Unix()
+// JSON returns an object formatted as expected to be serialized to JSON and served.
+func (s Stats) JSON(filter dsdata.Filter, params url.Values) dsdata.StatsOld {
+	// TODO fix to be the time calculated, not the time requested
+	now := s.Time.UnixNano() / int64(time.Millisecond) // Traffic Monitor 1.0 API is 'ms since the epoch'
 	jsonObj := &dsdata.StatsOld{
+		CommonAPIData:   srvhttp.GetCommonAPIData(params, time.Now()),
 		DeliveryService: map[enum.DeliveryServiceName]map[dsdata.StatName][]dsdata.StatOld{},
-		QueryParams:     http_server.ParametersStr(params),
-		DateStr:         http_server.DateStr(time.Now()),
 	}
 
-	for deliveryService, stat := range dsStats.DeliveryService {
+	for deliveryService, stat := range s.DeliveryService {
 		if !filter.UseDeliveryService(deliveryService) {
 			continue
 		}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/deliveryservicedata/stat.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/deliveryservicedata/stat.go b/traffic_monitor/experimental/traffic_monitor/deliveryservicedata/stat.go
index 16680e4..cce4a8e 100644
--- a/traffic_monitor/experimental/traffic_monitor/deliveryservicedata/stat.go
+++ b/traffic_monitor/experimental/traffic_monitor/deliveryservicedata/stat.go
@@ -1,8 +1,29 @@
 package deliveryservicedata // TODO rename?
 
+/*
+ * 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.
+ */
+
+
 import (
 	"errors"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/enum"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/enum"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/srvhttp"
 	"net/url"
 	"time"
 )
@@ -15,25 +36,30 @@ type Filter interface {
 	WithinStatHistoryMax(int) bool
 }
 
+// StatName is the name of a stat.
 type StatName string
+
+// StatOld is the old JSON representation of a stat, from Traffic Monitor 1.0.
 type StatOld struct {
 	Time  int64  `json:"time"`
 	Value string `json:"value"`
 	Span  int    `json:"span,omitempty"`  // TODO set? remove?
 	Index int    `json:"index,omitempty"` // TODO set? remove?
 }
+
+// StatsOld is the old JSON representation of stats, from Traffic Monitor 1.0. It is designed to be serialized and returns from an API, and includes stat history for each delivery service, as well as data common to most endpoints.
 type StatsOld struct {
-	// TODO move QueryParams, DateStr to a 'EndpointCommon' struct
 	DeliveryService map[enum.DeliveryServiceName]map[StatName][]StatOld `json:"deliveryService"`
-	QueryParams     string                                              `json:"pp"`
-	DateStr         string                                              `json:"date"`
+	srvhttp.CommonAPIData
 }
 
+// StatsReadonly is a read-only interface for delivery service Stats, designed to be passed to multiple goroutine readers.
 type StatsReadonly interface {
 	Get(enum.DeliveryServiceName) (StatReadonly, bool)
 	JSON(Filter, url.Values) StatsOld
 }
 
+// StatReadonly is a read-only interface for a delivery service Stat, designed to be passed to multiple goroutine readers.
 type StatReadonly interface {
 	Copy() Stat
 	Common() StatCommonReadonly
@@ -42,6 +68,7 @@ type StatReadonly interface {
 	Total() StatCacheStats
 }
 
+// StatCommonReadonly is a read-only interface for a delivery service's common Stat data, designed to be passed to multiple goroutine readers.
 type StatCommonReadonly interface {
 	Copy() StatCommon
 	CachesConfigured() StatInt
@@ -53,27 +80,36 @@ type StatCommonReadonly interface {
 	CachesAvailable() StatInt
 }
 
-// New, more structured format:
+// StatMeta includes metadata about a particular stat.
 type StatMeta struct {
-	Time int `json:"time"`
+	Time int64 `json:"time"`
 }
+
+// StatFloat is a float stat, combined with its metadata
 type StatFloat struct {
 	StatMeta
 	Value float64 `json:"value"`
 }
+
+// StatBool is a boolean stat, combined with its metadata
 type StatBool struct {
 	StatMeta
 	Value bool `json:"value"`
 }
+
+// StatInt is an integer stat, combined with its metadata
 type StatInt struct {
 	StatMeta
 	Value int64 `json:"value"`
 }
+
+// StatString is a string stat, combined with its metadata
 type StatString struct {
 	StatMeta
 	Value string `json:"value"`
 }
 
+// StatCommon contains stat data common to most delivery service stats.
 type StatCommon struct {
 	CachesConfiguredNum StatInt                 `json:"caches_configured"`
 	CachesReporting     map[enum.CacheName]bool `json:"caches_reporting"`
@@ -84,6 +120,7 @@ type StatCommon struct {
 	CachesAvailableNum  StatInt                 `json:"caches_available"`
 }
 
+// Copy returns a deep copy of this StatCommon object.
 func (a StatCommon) Copy() StatCommon {
 	b := a
 	for k, v := range a.CachesReporting {
@@ -92,32 +129,47 @@ func (a StatCommon) Copy() StatCommon {
 	return b
 }
 
+// CachesConfigured returns the number of caches configured for this delivery service stat. It is part of the StatCommonReadonly interface.
 func (a StatCommon) CachesConfigured() StatInt {
 	return a.CachesConfiguredNum
 }
+
+// CacheReporting returns the number of caches reporting for this delivery service stat. It is part of the StatCommonReadonly interface.
 func (a StatCommon) CacheReporting(name enum.CacheName) (bool, bool) {
 	c, ok := a.CachesReporting[name]
 	return c, ok
 }
+
+// CachesReportingNames returns the list of caches reporting for this delivery service stat. It is part of the StatCommonReadonly interface.
 func (a StatCommon) CachesReportingNames() []enum.CacheName {
 	names := make([]enum.CacheName, 0, len(a.CachesReporting))
-	for name, _ := range a.CachesReporting {
+	for name := range a.CachesReporting {
 		names = append(names, name)
 	}
 	return names
 }
+
+// Error returns the error string of this delivery service stat. It is part of the StatCommonReadonly interface.
 func (a StatCommon) Error() StatString {
 	return a.ErrorStr
 }
+
+// Status returns the status string of this delivery service stat. It is part of the StatCommonReadonly interface.
 func (a StatCommon) Status() StatString {
 	return a.StatusStr
 }
+
+// Healthy returns whether this delivery service is considered healthy by this stat. It is part of the StatCommonReadonly interface.
 func (a StatCommon) Healthy() StatBool {
 	return a.IsHealthy
 }
+
+// Available returns whether this delivery service is considered available by this stat. It is part of the StatCommonReadonly interface.
 func (a StatCommon) Available() StatBool {
 	return a.IsAvailable
 }
+
+// CachesAvailable returns the number of caches available to the delivery service in this stat. It is part of the StatCommonReadonly interface.
 func (a StatCommon) CachesAvailable() StatInt {
 	return a.CachesAvailableNum
 }
@@ -142,6 +194,7 @@ type StatCacheStats struct {
 	TpsTotal    StatInt    `json:"tps_total"`
 }
 
+// Sum adds the given cache stats to this cache stats. Numeric values are summed; strings are appended.
 func (a StatCacheStats) Sum(b StatCacheStats) StatCacheStats {
 	return StatCacheStats{
 		OutBytes:    StatInt{Value: a.OutBytes.Value + b.OutBytes.Value},
@@ -161,6 +214,7 @@ func (a StatCacheStats) Sum(b StatCacheStats) StatCacheStats {
 	}
 }
 
+// Stat represents a complete delivery service stat, for a given poll, or at the time requested.
 type Stat struct {
 	CommonStats        StatCommon
 	CacheGroups        map[enum.CacheGroupName]StatCacheStats
@@ -170,8 +224,10 @@ type Stat struct {
 	TotalStats         StatCacheStats
 }
 
+// ErrNotProcessedStat indicates a stat received is not used by Traffic Monitor, nor returned by any API endpoint. Receiving this error indicates the stat has been discarded.
 var ErrNotProcessedStat = errors.New("This stat is not used.")
 
+// NewStat returns a new delivery service Stat, initializing pointer members.
 func NewStat() *Stat {
 	return &Stat{
 		CacheGroups:        map[enum.CacheGroupName]StatCacheStats{},
@@ -182,6 +238,7 @@ func NewStat() *Stat {
 	}
 }
 
+// Copy performs a deep copy of this Stat. It does not modify, and is thus safe for multiple goroutines.
 func (a Stat) Copy() Stat {
 	b := Stat{
 		CommonStats:        a.CommonStats.Copy(),
@@ -206,20 +263,24 @@ func (a Stat) Copy() Stat {
 	return b
 }
 
+// Common returns the common stat data for this stat. It is part of the StatCommonReadonly interface.
 func (a Stat) Common() StatCommonReadonly {
 	return a.CommonStats
 }
 
+// CacheGroup returns the data for the given cachegroup in this stat. It is part of the StatCommonReadonly interface.
 func (a Stat) CacheGroup(name enum.CacheGroupName) (StatCacheStats, bool) {
 	c, ok := a.CacheGroups[name]
 	return c, ok
 }
 
+// Type returns the aggregated data for the given cache type in this stat. It is part of the StatCommonReadonly interface.
 func (a Stat) Type(name enum.CacheType) (StatCacheStats, bool) {
 	t, ok := a.Types[name]
 	return t, ok
 }
 
+// Total returns the aggregated total data in this stat. It is part of the StatCommonReadonly interface.
 func (a Stat) Total() StatCacheStats {
 	return a.TotalStats
 }

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/enum/enum.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/enum/enum.go b/traffic_monitor/experimental/traffic_monitor/enum/enum.go
index d14593c..77f8ea4 100644
--- a/traffic_monitor/experimental/traffic_monitor/enum/enum.go
+++ b/traffic_monitor/experimental/traffic_monitor/enum/enum.go
@@ -1,29 +1,56 @@
-// enum contains enumerations and strongly typed names.
+// Package enum contains enumerations and strongly typed names.
 // The names are an experiment with strong typing of string types. The primary goal is to make code more self-documenting, especially map keys. If peole don't like it, we can get rid of it.
 package enum
 
+/*
+ * 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.
+ */
+
+
 import (
 	"strings"
 )
 
+// TrafficMonitorName is the hostname of a Traffic Monitor peer.
 type TrafficMonitorName string
 
+// CacheName is the hostname of a CDN cache.
 type CacheName string
 
+// CacheGroupName is the name of a CDN cachegroup.
 type CacheGroupName string
 
-// Current JSON endpoint:
+// DeliveryServiceName is the name of a CDN delivery service.
 type DeliveryServiceName string
 
-// TODO move and rename more generically
+// CacheType is the type (or tier) of a CDN cache.
 type CacheType string
 
 const (
-	CacheTypeEdge    = CacheType("EDGE")
-	CacheTypeMid     = CacheType("MID")
+	// CacheTypeEdge represents an edge cache.
+	CacheTypeEdge = CacheType("EDGE")
+	// CacheTypeMid represents a mid cache.
+	CacheTypeMid = CacheType("MID")
+	// CacheTypeInvalid represents an cache type enumeration. Note this is the default construction for a CacheType.
 	CacheTypeInvalid = CacheType("")
 )
 
+// String returns a string representation of this cache type.
 func (t CacheType) String() string {
 	switch t {
 	case CacheTypeEdge:
@@ -31,10 +58,11 @@ func (t CacheType) String() string {
 	case CacheTypeMid:
 		return "MID"
 	default:
-		return "INVALID"
+		return "INVALIDCACHETYPE"
 	}
 }
 
+// CacheTypeFromString returns a cache type object from its string representation, or CacheTypeInvalid if the string is not a valid type.
 func CacheTypeFromString(s string) CacheType {
 	s = strings.ToLower(s)
 	switch s {
@@ -51,11 +79,15 @@ func CacheTypeFromString(s string) CacheType {
 type DSType string
 
 const (
-	DSTypeHTTP    = DSType("http")
-	DSTypeDNS     = DSType("dns")
+	// DSTypeHTTP represents an HTTP delivery service
+	DSTypeHTTP = DSType("http")
+	// DSTypeDNS represents a DNS delivery service
+	DSTypeDNS = DSType("dns")
+	// DSTypeInvalid represents an invalid delivery service type enumeration. Note this is the default construction for a DSType.
 	DSTypeInvalid = DSType("")
 )
 
+// String returns a string representation of this delivery service type.
 func (t DSType) String() string {
 	switch t {
 	case DSTypeHTTP:
@@ -63,10 +95,11 @@ func (t DSType) String() string {
 	case DSTypeDNS:
 		return "DNS"
 	default:
-		return "INVALID"
+		return "INVALIDDSTYPE"
 	}
 }
 
+// DSTypeFromString returns a delivery service type object from its string representation, or DSTypeInvalid if the string is not a valid type.
 func DSTypeFromString(s string) DSType {
 	s = strings.ToLower(s)
 	switch s {
@@ -78,3 +111,54 @@ func DSTypeFromString(s string) DSType {
 		return DSTypeInvalid
 	}
 }
+
+// CacheStatus represents the Traffic Server status set in Traffic Ops (online, offline, admin_down, reported). The string values of this type should match the Traffic Ops values.
+type CacheStatus string
+
+const (
+	// CacheStatusAdminDown represents a cache which has been administratively marked as down, but which should still appear in the CDN (Traffic Server, Traffic Monitor, Traffic Router).
+	CacheStatusAdminDown = CacheStatus("ADMIN_DOWN")
+	// CacheStatusOnline represents a cache which has been marked as Online in Traffic Ops, irrespective of monitoring. Traffic Monitor will always flag these caches as available.
+	CacheStatusOnline = CacheStatus("ONLINE")
+	// CacheStatusOffline represents a cache which has been marked as Offline in Traffic Ops. These caches will not be returned in any endpoint, and Traffic Monitor acts like they don't exist.
+	CacheStatusOffline = CacheStatus("OFFLINE")
+	// CacheStatusReported represents a cache which has been marked as Reported in Traffic Ops. These caches are polled for health and returned in endpoints as available or unavailable based on bandwidth, response time, and other factors. The vast majority of caches should be Reported.
+	CacheStatusReported = CacheStatus("REPORTED")
+	// CacheStatusInvalid represents an invalid status enumeration.
+	CacheStatusInvalid = CacheStatus("")
+)
+
+// String returns a string representation of this cache status
+func (t CacheStatus) String() string {
+	switch t {
+	case CacheStatusAdminDown:
+		fallthrough
+	case CacheStatusOnline:
+		fallthrough
+	case CacheStatusOffline:
+		fallthrough
+	case CacheStatusReported:
+		return string(t)
+	default:
+		return "INVALIDCACHESTATUS"
+	}
+}
+
+// CacheStatusFromString returns a CacheStatus from its string representation, or CacheStatusInvalid if the string is not a valid type.
+func CacheStatusFromString(s string) CacheStatus {
+	s = strings.ToLower(s)
+	switch s {
+	case "admin_down":
+		fallthrough
+	case "admindown":
+		return CacheStatusAdminDown
+	case "offline":
+		return CacheStatusOffline
+	case "online":
+		return CacheStatusOnline
+	case "reported":
+		return CacheStatusReported
+	default:
+		return CacheStatusInvalid
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/health/cache_health.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/health/cache_health.go b/traffic_monitor/experimental/traffic_monitor/health/cache_health.go
index b8b180f..5dfa0c2 100644
--- a/traffic_monitor/experimental/traffic_monitor/health/cache_health.go
+++ b/traffic_monitor/experimental/traffic_monitor/health/cache_health.go
@@ -1,43 +1,44 @@
 package health
 
-import (
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/common/log"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/cache"
-	traffic_ops "github.com/Comcast/traffic_control/traffic_ops/client"
+/*
+ * 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.
+ */
+
 
+import (
 	"fmt"
+	"math"
 	"strconv"
 	"strings"
-)
-
-// Get the String value of one of those pesky map[string]interface{} things that seem so easy
-func getString(key string, intface map[string]interface{}) (string, error) {
-	str, ok := intface[key].(string)
-
-	if ok {
-		return str, nil
-	} else {
-		return "", fmt.Errorf("Error in getString: No string found for key %s", key)
-	}
-}
+	"time"
 
-// Get the float64 value of one of those pesky map[string]interface{} things that seem so easy
-func getNumber(key string, intface map[string]interface{}) (float64, error) {
-	val, ok := intface[key].(float64)
-
-	if ok {
-		return val, nil
-	} else {
-		return -1, fmt.Errorf("Error in getNumber: No number found for %s", key)
-	}
-}
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/common/log"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/cache"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/enum"
+	traffic_ops "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
 
 func setError(newResult *cache.Result, err error) {
 	newResult.Error = err
 	newResult.Available = false
 }
 
-// Get the vitals to decide health on in the right format
+// GetVitals Gets the vitals to decide health on in the right format
 func GetVitals(newResult *cache.Result, prevResult *cache.Result, mc *traffic_ops.TrafficMonitorConfigMap) {
 	if newResult.Error != nil {
 		log.Errorf("cache_health.GetVitals() called with an errored Result!")
@@ -54,7 +55,7 @@ func GetVitals(newResult *cache.Result, prevResult *cache.Result, mc *traffic_op
 		}
 		newResult.Vitals.LoadAvg = oneMinAvg
 	} else {
-		setError(newResult, fmt.Errorf("Can't make sense of '%s' as a load average for %s", newResult.Astats.System.ProcLoadavg, newResult.Id))
+		setError(newResult, fmt.Errorf("Can't make sense of '%s' as a load average for %s", newResult.Astats.System.ProcLoadavg, newResult.ID))
 		return
 	}
 
@@ -90,27 +91,63 @@ func GetVitals(newResult *cache.Result, prevResult *cache.Result, mc *traffic_op
 	// inf.speed -- value looks like "10000" (without the quotes) so it is in Mbps.
 	// TODO JvD: Should we really be running this code every second for every cache polled????? I don't think so.
 	interfaceBandwidth := newResult.Astats.System.InfSpeed
-	newResult.Vitals.MaxKbpsOut = int64(interfaceBandwidth)*1000 - mc.Profile[mc.TrafficServer[string(newResult.Id)].Profile].Parameters.MinFreeKbps
+	newResult.Vitals.MaxKbpsOut = int64(interfaceBandwidth)*1000 - mc.Profile[mc.TrafficServer[string(newResult.ID)].Profile].Parameters.MinFreeKbps
 
 	// log.Infoln(newResult.Id, "BytesOut", newResult.Vitals.BytesOut, "BytesIn", newResult.Vitals.BytesIn, "Kbps", newResult.Vitals.KbpsOut, "max", newResult.Vitals.MaxKbpsOut)
 }
 
+// getKbpsThreshold returns the numeric kbps threshold, from the Traffic Ops string value. If there is a parse error, it logs a warning and returns the max floating point number, signifying no limit
+// TODO add float64 to Traffic Ops Client interface
+func getKbpsThreshold(threshStr string) int64 {
+	if len(threshStr) == 0 {
+		log.Errorf("Empty Traffic Ops HealthThresholdAvailableBandwidthInKbps; setting no limit.\n")
+		return math.MaxInt64
+	}
+	if threshStr[0] == '>' {
+		threshStr = threshStr[1:]
+	}
+	thresh, err := strconv.ParseInt(threshStr, 10, 64)
+	if err != nil {
+		log.Errorf("Failed to parse Traffic Ops HealthThresholdAvailableBandwidthInKbps, setting no limit: '%v'\n", err)
+		return math.MaxInt64
+	}
+	return thresh
+}
+
+// TODO add time.Duration to Traffic Ops Client interface
+func getQueryThreshold(threshInt int64) time.Duration {
+	return time.Duration(threshInt) * time.Millisecond
+}
+
+func cacheCapacityKbps(result cache.Result) int64 {
+	kbpsInMbps := int64(1000)
+	return int64(result.Astats.System.InfSpeed) * kbpsInMbps
+}
+
 // EvalCache returns whether the given cache should be marked available, and a string describing why
 func EvalCache(result cache.Result, mc *traffic_ops.TrafficMonitorConfigMap) (bool, string) {
-	status := mc.TrafficServer[string(result.Id)].Status
+	toServer := mc.TrafficServer[string(result.ID)]
+	status := enum.CacheStatusFromString(toServer.Status)
+	if status == enum.CacheStatusInvalid {
+		log.Errorf("Cache %v got invalid status from Traffic Ops '%v' - treating as Reported\n", result.ID, toServer.Status)
+	}
+	params := mc.Profile[toServer.Profile].Parameters
 	switch {
-	case status == "ADMIN_DOWN":
-		return false, "set to ADMIN_DOWN"
-	case status == "OFFLINE":
-		return false, "set to OFFLINE"
-	case status == "ONLINE":
-		return true, "set to ONLINE"
+	case status == enum.CacheStatusAdminDown:
+		return false, "set to " + status.String()
+	case status == enum.CacheStatusOffline:
+		log.Errorf("Cache %v set to offline, but still polled\n", result.ID)
+		return false, "set to " + status.String()
+	case status == enum.CacheStatusOnline:
+		return true, "set to " + status.String()
 	case result.Error != nil:
 		return false, fmt.Sprintf("error: %v", result.Error)
-	case result.Vitals.LoadAvg > mc.Profile[mc.TrafficServer[string(result.Id)].Profile].Parameters.HealthThresholdLoadAvg:
-		return false, fmt.Sprintf("load average %f exceeds threshold %f", result.Vitals.LoadAvg, mc.Profile[mc.TrafficServer[string(result.Id)].Profile].Parameters.HealthThresholdLoadAvg)
-	case result.Vitals.MaxKbpsOut < result.Vitals.KbpsOut:
-		return false, fmt.Sprintf("%dkbps exceeds max %dkbps", result.Vitals.KbpsOut, result.Vitals.MaxKbpsOut)
+	case result.Vitals.LoadAvg > params.HealthThresholdLoadAvg:
+		return false, fmt.Sprintf("load average %f exceeds threshold %f", result.Vitals.LoadAvg, params.HealthThresholdLoadAvg)
+	case result.Vitals.KbpsOut > cacheCapacityKbps(result)-getKbpsThreshold(params.HealthThresholdAvailableBandwidthInKbps):
+		return false, fmt.Sprintf("%dkbps exceeds max %dkbps", result.Vitals.KbpsOut, getKbpsThreshold(params.HealthThresholdAvailableBandwidthInKbps))
+	case result.RequestTime > getQueryThreshold(int64(params.HealthThresholdQueryTime)):
+		return false, fmt.Sprintf("request time %v exceeds max %v", result.RequestTime, getQueryThreshold(int64(params.HealthThresholdQueryTime)))
 	default:
 		return result.Available, "reported"
 	}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/http_server/http_server.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/http_server/http_server.go b/traffic_monitor/experimental/traffic_monitor/http_server/http_server.go
deleted file mode 100644
index fb70d72..0000000
--- a/traffic_monitor/experimental/traffic_monitor/http_server/http_server.go
+++ /dev/null
@@ -1,289 +0,0 @@
-package http_server
-
-import (
-	"fmt"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/common/log"
-	"github.com/hydrogen18/stoppableListener"
-	"io/ioutil"
-	"net"
-	"net/http"
-	"net/url"
-	"sync"
-	"time"
-)
-
-// Server is a re-runnable HTTP server. Server.Run() may be called repeatedly, and
-// each time the previous running server will be stopped, and the server will be
-// restarted with the new port address and data request channel.
-type Server struct {
-	getData                    GetDataFunc
-	stoppableListener          *stoppableListener.StoppableListener
-	stoppableListenerWaitGroup sync.WaitGroup
-}
-
-// Endpoints returns a map of HTTP paths to functions.
-// This is a function because Go doesn't have constant map literals.
-func (s Server) endpoints() (map[string]http.HandlerFunc, error) {
-	handleRoot, err := s.handleRootFunc()
-	handleSortableJs, err := s.handleSortableFunc()
-	if err != nil {
-		return nil, fmt.Errorf("Error getting root endpoint: %v", err)
-	}
-
-	// note: with the trailing slash, any non-trailing slash requests will get a 301 redirect
-	return map[string]http.HandlerFunc{
-		"/publish/CacheStats/":          s.dataRequestFunc(CacheStats),
-		"/publish/CacheStats":           s.dataRequestFunc(CacheStats),
-		"/publish/CrConfig/":            s.dataRequestFunc(TRConfig),
-		"/publish/CrConfig":             s.dataRequestFunc(TRConfig),
-		"/publish/CrStates/":            s.handleCrStatesFunc(),
-		"/publish/CrStates":             s.handleCrStatesFunc(),
-		"/publish/DsStats/":             s.dataRequestFunc(DSStats),
-		"/publish/DsStats":              s.dataRequestFunc(DSStats),
-		"/publish/EventLog/":            s.dataRequestFunc(EventLog),
-		"/publish/EventLog":             s.dataRequestFunc(EventLog),
-		"/publish/PeerStates/":          s.dataRequestFunc(PeerStates),
-		"/publish/PeerStates":           s.dataRequestFunc(PeerStates),
-		"/publish/StatSummary/":         s.dataRequestFunc(StatSummary),
-		"/publish/StatSummary":          s.dataRequestFunc(StatSummary),
-		"/publish/Stats/":               s.dataRequestFunc(Stats),
-		"/publish/Stats":                s.dataRequestFunc(Stats),
-		"/publish/ConfigDoc/":           s.dataRequestFunc(ConfigDoc),
-		"/publish/ConfigDoc":            s.dataRequestFunc(ConfigDoc),
-		"/api/cache-count/":             s.dataRequestFunc(APICacheCount),
-		"/api/cache-count":              s.dataRequestFunc(APICacheCount),
-		"/api/cache-available-count/":   s.dataRequestFunc(APICacheAvailableCount),
-		"/api/cache-available-count":    s.dataRequestFunc(APICacheAvailableCount),
-		"/api/cache-down-count/":        s.dataRequestFunc(APICacheDownCount),
-		"/api/cache-down-count":         s.dataRequestFunc(APICacheDownCount),
-		"/api/version/":                 s.dataRequestFunc(APIVersion),
-		"/api/version":                  s.dataRequestFunc(APIVersion),
-		"/api/traffic-ops-uri/":         s.dataRequestFunc(APITrafficOpsURI),
-		"/api/traffic-ops-uri":          s.dataRequestFunc(APITrafficOpsURI),
-		"/api/cache-statuses/":          s.dataRequestFunc(APICacheStates),
-		"/api/cache-statuses":           s.dataRequestFunc(APICacheStates),
-		"/api/bandwidth-kbps/":          s.dataRequestFunc(APIBandwidthKbps),
-		"/api/bandwidth-kbps":           s.dataRequestFunc(APIBandwidthKbps),
-		"/api/bandwidth-capacity-kbps/": s.dataRequestFunc(APIBandwidthCapacityKbps),
-		"/api/bandwidth-capacity-kbps":  s.dataRequestFunc(APIBandwidthCapacityKbps),
-		"/":             handleRoot,
-		"/sorttable.js": handleSortableJs,
-	}, nil
-}
-
-func (s Server) registerEndpoints(sm *http.ServeMux) error {
-	endpoints, err := s.endpoints()
-	if err != nil {
-		return err
-	}
-	for path, f := range endpoints {
-		sm.HandleFunc(path, f)
-	}
-	return nil
-}
-
-// Run runs a new HTTP service at the given addr, making data requests to the given c.
-// Run may be called repeatedly, and each time, will shut down any existing service first.
-// Run is NOT threadsafe, and MUST NOT be called concurrently by multiple goroutines.
-func (s Server) Run(f GetDataFunc, addr string) error {
-	// TODO make an object, which itself is not threadsafe, but which encapsulates all data so multiple
-	//      objects can be created and Run.
-
-	if s.stoppableListener != nil {
-		log.Infof("Stopping Web Server\n")
-		s.stoppableListener.Stop()
-		s.stoppableListenerWaitGroup.Wait()
-	}
-	log.Infof("Starting Web Server\n")
-
-	var err error
-	var originalListener net.Listener
-	if originalListener, err = net.Listen("tcp", addr); err != nil {
-		return err
-	}
-	if s.stoppableListener, err = stoppableListener.New(originalListener); err != nil {
-		return err
-	}
-
-	s.getData = f
-
-	sm := http.NewServeMux()
-	err = s.registerEndpoints(sm)
-	if err != nil {
-		return err
-	}
-	server := &http.Server{
-		Addr:           addr,
-		Handler:        sm,
-		ReadTimeout:    10 * time.Second,
-		WriteTimeout:   10 * time.Second,
-		MaxHeaderBytes: 1 << 20,
-	}
-
-	s.stoppableListenerWaitGroup = sync.WaitGroup{}
-	s.stoppableListenerWaitGroup.Add(1)
-	go func() {
-		defer s.stoppableListenerWaitGroup.Done()
-		server.Serve(s.stoppableListener)
-	}()
-
-	log.Infof("Web server listening on %s", addr)
-	return nil
-}
-
-type Type int
-
-const (
-	TRConfig Type = (1 << iota)
-	TRStateDerived
-	TRStateSelf
-	CacheStats
-	DSStats
-	EventLog
-	PeerStates
-	StatSummary
-	Stats
-	ConfigDoc
-	APICacheCount
-	APICacheAvailableCount
-	APICacheDownCount
-	APIVersion
-	APITrafficOpsURI
-	APICacheStates
-	APIBandwidthKbps
-	APIBandwidthCapacityKbps
-)
-
-func (t Type) String() string {
-	switch t {
-	case TRConfig:
-		return "TRConfig"
-	case TRStateDerived:
-		return "TRStateDerived"
-	case TRStateSelf:
-		return "TRStateSelf"
-	case CacheStats:
-		return "CacheStats"
-	case DSStats:
-		return "DSStats"
-	case EventLog:
-		return "EventLog"
-	case PeerStates:
-		return "PeerStates"
-	case StatSummary:
-		return "StatSummary"
-	case Stats:
-		return "Stats"
-	case ConfigDoc:
-		return "ConfigDoc"
-	case APICacheCount:
-		return "APICacheCount"
-	case APICacheAvailableCount:
-		return "APICacheAvailableCount"
-	case APICacheDownCount:
-		return "APICacheDownCount"
-	case APIVersion:
-		return "APIVersion"
-	case APITrafficOpsURI:
-		return "APITrafficOpsURI"
-	case APICacheStates:
-		return "APICacheStates"
-	case APIBandwidthKbps:
-		return "APIBandwidthKbps"
-	case APIBandwidthCapacityKbps:
-		return "APIBandwidthCapacityKbps"
-	default:
-		return "Invalid"
-	}
-}
-
-type Format int
-
-const (
-	XML Format = (1 << iota)
-	JSON
-)
-
-type DataRequest struct {
-	Type
-	Format
-	Date       string
-	Parameters map[string][]string
-}
-
-type GetDataFunc func(DataRequest) ([]byte, int)
-
-// ParametersStr takes the URL query parameters, and returns a string as used by the Traffic Monitor 1.0 endpoints "pp" key.
-func ParametersStr(params url.Values) string {
-	fmt.Println("debug4 ParametersStr 0")
-	pp := ""
-	for param, vals := range params {
-		for _, val := range vals {
-			pp += param + "=[" + val + "], "
-		}
-	}
-	if len(pp) > 2 {
-		pp = pp[:len(pp)-2]
-	}
-	return pp
-}
-
-// DateStr returns the given time in the format expected by Traffic Monitor 1.0 API users
-func DateStr(t time.Time) string {
-	return t.UTC().Format("Mon Jan 02 15:04:05 UTC 2006")
-}
-
-func (s Server) dataRequest(w http.ResponseWriter, req *http.Request, t Type, f Format) {
-	//pp: "0=[my-ats-edge-cache-0], hc=[1]",
-	//dateLayout := "Thu Oct 09 20:28:36 UTC 2014"
-	dateLayout := "Mon Jan 02 15:04:05 MST 2006"
-	data, responseCode := s.getData(DataRequest{
-		Type:       t,
-		Format:     f,
-		Date:       time.Now().UTC().Format(dateLayout),
-		Parameters: req.URL.Query(),
-	})
-	if len(data) > 0 {
-		w.WriteHeader(responseCode)
-		w.Write(data)
-	} else {
-		w.WriteHeader(http.StatusInternalServerError)
-		w.Write([]byte("Internal Server Error"))
-	}
-}
-
-func (s Server) handleRootFunc() (http.HandlerFunc, error) {
-	index, err := ioutil.ReadFile("index.html")
-	if err != nil {
-		return nil, err
-	}
-	return func(w http.ResponseWriter, req *http.Request) {
-		fmt.Fprintf(w, "%s", index)
-	}, nil
-}
-
-func (s Server) handleSortableFunc() (http.HandlerFunc, error) {
-	index, err := ioutil.ReadFile("sorttable.js")
-	if err != nil {
-		return nil, err
-	}
-	return func(w http.ResponseWriter, req *http.Request) {
-		fmt.Fprintf(w, "%s", index)
-	}, nil
-}
-
-func (s Server) handleCrStatesFunc() http.HandlerFunc {
-	return func(w http.ResponseWriter, req *http.Request) {
-		t := TRStateDerived
-		if req.URL.RawQuery == "raw" {
-			t = TRStateSelf
-		}
-		s.dataRequest(w, req, t, JSON)
-	}
-}
-
-func (s Server) dataRequestFunc(t Type) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		s.dataRequest(w, r, t, JSON)
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/index.html
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/index.html b/traffic_monitor/experimental/traffic_monitor/index.html
index a5c43aa..43d1ab4 100644
--- a/traffic_monitor/experimental/traffic_monitor/index.html
+++ b/traffic_monitor/experimental/traffic_monitor/index.html
@@ -1,3 +1,22 @@
+<!--
+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.
+-->
+
 <!DOCTYPE html>
 <html>
 	<head>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/manager/cacheavailablestatus.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/manager/cacheavailablestatus.go b/traffic_monitor/experimental/traffic_monitor/manager/cacheavailablestatus.go
index b66c392..67860b1 100644
--- a/traffic_monitor/experimental/traffic_monitor/manager/cacheavailablestatus.go
+++ b/traffic_monitor/experimental/traffic_monitor/manager/cacheavailablestatus.go
@@ -1,25 +1,50 @@
 package manager
 
+/*
+ * 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.
+ */
+
+
 import (
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/enum"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/enum"
 	"sync"
 )
 
+// CacheAvailableStatusReported is the status string returned by caches set to "reported" in Traffic Ops.
 // TODO put somewhere more generic
 const CacheAvailableStatusReported = "REPORTED"
 
+// CacheAvailableStatus is the available status of the given cache. It includes a boolean available/unavailable flag, and a descriptive string.
 type CacheAvailableStatus struct {
 	Available bool
 	Status    string
 }
 
+// CacheAvailableStatuses is the available status of each cache.
 type CacheAvailableStatuses map[enum.CacheName]CacheAvailableStatus
 
+// CacheAvailableStatusThreadsafe wraps a map of cache available statuses to be safe for multiple reader goroutines and one writer.
 type CacheAvailableStatusThreadsafe struct {
 	caches *CacheAvailableStatuses
 	m      *sync.RWMutex
 }
 
+// Copy copies this CacheAvailableStatuses. It does not modify, and thus is safe for multiple reader goroutines.
 func (a CacheAvailableStatuses) Copy() CacheAvailableStatuses {
 	b := CacheAvailableStatuses(map[enum.CacheName]CacheAvailableStatus{})
 	for k, v := range a {
@@ -28,17 +53,20 @@ func (a CacheAvailableStatuses) Copy() CacheAvailableStatuses {
 	return b
 }
 
+// NewCacheAvailableStatusThreadsafe creates and returns a new CacheAvailableStatusThreadsafe, initializing internal pointer values.
 func NewCacheAvailableStatusThreadsafe() CacheAvailableStatusThreadsafe {
 	c := CacheAvailableStatuses(map[enum.CacheName]CacheAvailableStatus{})
 	return CacheAvailableStatusThreadsafe{m: &sync.RWMutex{}, caches: &c}
 }
 
+// Get returns the internal map of cache statuses. The returned map MUST NOT be modified. If modification is necessary, copy.
 func (o *CacheAvailableStatusThreadsafe) Get() CacheAvailableStatuses {
 	o.m.RLock()
 	defer o.m.RUnlock()
 	return *o.caches
 }
 
+// Set sets the internal map of cache availability. This MUST NOT be called by multiple goroutines.
 func (o *CacheAvailableStatusThreadsafe) Set(v CacheAvailableStatuses) {
 	o.m.Lock()
 	*o.caches = v

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/manager/datarequest.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/manager/datarequest.go b/traffic_monitor/experimental/traffic_monitor/manager/datarequest.go
index 4651aa3..7de4c0e 100644
--- a/traffic_monitor/experimental/traffic_monitor/manager/datarequest.go
+++ b/traffic_monitor/experimental/traffic_monitor/manager/datarequest.go
@@ -1,5 +1,25 @@
 package manager
 
+/*
+ * 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.
+ */
+
+
 import (
 	"encoding/json"
 	"fmt"
@@ -11,31 +31,35 @@ import (
 	"strings"
 	"time"
 
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/common/log"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/cache"
-	ds "github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/deliveryservice"
-	dsdata "github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/deliveryservicedata"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/enum"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/http_server"
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/peer"
-	todata "github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/trafficopsdata"
-	towrap "github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/trafficopswrapper"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/common/log"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/cache"
+	ds "github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/deliveryservice"
+	dsdata "github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/deliveryservicedata"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/enum"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/peer"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/srvhttp"
+	todata "github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/trafficopsdata"
+	towrap "github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/trafficopswrapper"
+	to "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
 )
 
+// JSONEvents represents the structure we wish to serialize to JSON, for Events.
 type JSONEvents struct {
 	Events []Event `json:"events"`
 }
 
+// CacheState represents the available state of a cache.
 type CacheState struct {
 	Value bool `json:"value"`
 }
 
-type ApiPeerStates struct {
-	Peers       map[enum.TrafficMonitorName]map[enum.CacheName][]CacheState `json:"peers"`
-	QueryParams string                                                      `json:"pp"`
-	DateStr     string                                                      `json:"date"`
+// APIPeerStates contains the data to be returned for an API call to get the peer states of a Traffic Monitor. This contains common API data returned by most endpoints, and a map of peers, to caches' states.
+type APIPeerStates struct {
+	srvhttp.CommonAPIData
+	Peers map[enum.TrafficMonitorName]map[enum.CacheName][]CacheState `json:"peers"`
 }
 
+// CacheStatus contains summary stat data about the given cache.
 // TODO make fields nullable, so error fields can be omitted, letting API callers still get updates for unerrored fields
 type CacheStatus struct {
 	Type                  *string  `json:"type,omitempty"`
@@ -56,6 +80,7 @@ type CacheStatFilter struct {
 	cacheTypes   map[enum.CacheName]enum.CacheType
 }
 
+// UseCache returns whether the given cache is in the filter.
 func (f *CacheStatFilter) UseCache(name enum.CacheName) bool {
 	if _, inHosts := f.hosts[name]; len(f.hosts) != 0 && !inHosts {
 		return false
@@ -66,6 +91,7 @@ func (f *CacheStatFilter) UseCache(name enum.CacheName) bool {
 	return true
 }
 
+// UseStat returns whether the given stat is in the filter.
 func (f *CacheStatFilter) UseStat(statName string) bool {
 	if len(f.statsToUse) == 0 {
 		return true
@@ -74,7 +100,7 @@ func (f *CacheStatFilter) UseStat(statName string) bool {
 		_, ok := f.statsToUse[statName]
 		return ok
 	}
-	for statToUse, _ := range f.statsToUse {
+	for statToUse := range f.statsToUse {
 		if strings.Contains(statName, statToUse) {
 			return true
 		}
@@ -82,6 +108,7 @@ func (f *CacheStatFilter) UseStat(statName string) bool {
 	return false
 }
 
+// WithinStatHistoryMax returns whether the given history index is less than the max history of this filter.
 func (f *CacheStatFilter) WithinStatHistoryMax(n int) bool {
 	if f.historyCount == 0 {
 		return true
@@ -103,7 +130,7 @@ func NewCacheStatFilter(params url.Values, cacheTypes map[enum.CacheName]enum.Ca
 	if len(params) > len(validParams) {
 		return nil, fmt.Errorf("invalid query parameters")
 	}
-	for param, _ := range params {
+	for param := range params {
 		if _, ok := validParams[param]; !ok {
 			return nil, fmt.Errorf("invalid query parameter '%v'", param)
 		}
@@ -172,6 +199,7 @@ type DSStatFilter struct {
 	dsTypes          map[enum.DeliveryServiceName]enum.DSType
 }
 
+// UseDeliveryService returns whether the given delivery service is in this filter.
 func (f *DSStatFilter) UseDeliveryService(name enum.DeliveryServiceName) bool {
 	if _, inDSes := f.deliveryServices[name]; len(f.deliveryServices) != 0 && !inDSes {
 		return false
@@ -182,6 +210,7 @@ func (f *DSStatFilter) UseDeliveryService(name enum.DeliveryServiceName) bool {
 	return true
 }
 
+// UseStat returns whether the given stat is in this filter.
 func (f *DSStatFilter) UseStat(statName string) bool {
 	if len(f.statsToUse) == 0 {
 		return true
@@ -190,7 +219,7 @@ func (f *DSStatFilter) UseStat(statName string) bool {
 		_, ok := f.statsToUse[statName]
 		return ok
 	}
-	for statToUse, _ := range f.statsToUse {
+	for statToUse := range f.statsToUse {
 		if strings.Contains(statName, statToUse) {
 			return true
 		}
@@ -198,6 +227,7 @@ func (f *DSStatFilter) UseStat(statName string) bool {
 	return false
 }
 
+// WithinStatHistoryMax returns whether the given history index is less than the max history of this filter.
 func (f *DSStatFilter) WithinStatHistoryMax(n int) bool {
 	if f.historyCount == 0 {
 		return true
@@ -219,7 +249,7 @@ func NewDSStatFilter(params url.Values, dsTypes map[enum.DeliveryServiceName]enu
 	if len(params) > len(validParams) {
 		return nil, fmt.Errorf("invalid query parameters")
 	}
-	for param, _ := range params {
+	for param := range params {
 		if _, ok := validParams[param]; !ok {
 			return nil, fmt.Errorf("invalid query parameter '%v'", param)
 		}
@@ -289,6 +319,7 @@ type PeerStateFilter struct {
 	cacheTypes   map[enum.CacheName]enum.CacheType
 }
 
+// UsePeer returns whether the given Traffic Monitor peer is in this filter.
 func (f *PeerStateFilter) UsePeer(name enum.TrafficMonitorName) bool {
 	if _, inPeers := f.peersToUse[name]; len(f.peersToUse) != 0 && !inPeers {
 		return false
@@ -296,6 +327,7 @@ func (f *PeerStateFilter) UsePeer(name enum.TrafficMonitorName) bool {
 	return true
 }
 
+// UseCache returns whether the given cache is in this filter.
 func (f *PeerStateFilter) UseCache(name enum.CacheName) bool {
 	if f.cacheType != enum.CacheTypeInvalid && f.cacheTypes[name] != f.cacheType {
 		return false
@@ -309,7 +341,7 @@ func (f *PeerStateFilter) UseCache(name enum.CacheName) bool {
 		_, ok := f.cachesToUse[name]
 		return ok
 	}
-	for cacheToUse, _ := range f.cachesToUse {
+	for cacheToUse := range f.cachesToUse {
 		if strings.Contains(string(name), string(cacheToUse)) {
 			return true
 		}
@@ -317,6 +349,7 @@ func (f *PeerStateFilter) UseCache(name enum.CacheName) bool {
 	return false
 }
 
+// WithinStatHistoryMax returns whether the given history index is less than the max history of this filter.
 func (f *PeerStateFilter) WithinStatHistoryMax(n int) bool {
 	if f.historyCount == 0 {
 		return true
@@ -339,7 +372,7 @@ func NewPeerStateFilter(params url.Values, cacheTypes map[enum.CacheName]enum.Ca
 	if len(params) > len(validParams) {
 		return nil, fmt.Errorf("invalid query parameters")
 	}
-	for param, _ := range params {
+	for param := range params {
 		if _, ok := validParams[param]; !ok {
 			return nil, fmt.Errorf("invalid query parameter '%v'", param)
 		}
@@ -399,16 +432,16 @@ func NewPeerStateFilter(params url.Values, cacheTypes map[enum.CacheName]enum.Ca
 	}, nil
 }
 
-// DataRequest takes an `http_server.DataRequest`, and the monitored data objects, and returns the appropriate response, and the status code.
+// DataRequest takes an `srvhttp.DataRequest`, and the monitored data objects, and returns the appropriate response, and the status code.
 func DataRequest(
-	req http_server.DataRequest,
+	req srvhttp.DataRequest,
 	opsConfig OpsConfigThreadsafe,
 	toSession towrap.ITrafficOpsSession,
 	localStates peer.CRStatesThreadsafe,
 	peerStates peer.CRStatesPeersThreadsafe,
 	combinedStates peer.CRStatesThreadsafe,
 	statHistory StatHistoryThreadsafe,
-	dsStats DSStatsThreadsafe,
+	dsStats DSStatsReader,
 	events EventsThreadsafe,
 	staticAppData StaticAppData,
 	healthPollInterval time.Duration,
@@ -420,7 +453,8 @@ func DataRequest(
 	localCacheStatus CacheAvailableStatusThreadsafe,
 	lastStats LastStatsThreadsafe,
 	unpolledCaches UnpolledCachesThreadsafe,
-) (body []byte, responseCode int) {
+	monitorConfig TrafficMonitorConfigMapThreadsafe,
+) ([]byte, int) {
 
 	// handleErr takes an error, and the request type it came from, and logs. It is ok to call with a nil error, in which case this is a no-op.
 	handleErr := func(err error) {
@@ -431,7 +465,7 @@ func DataRequest(
 		log.Errorf("Request Error: %v\n", fmt.Errorf(req.Type.String()+": %v", err))
 	}
 
-	// commonReturn takes the body, err, and the data request Type which has been processed. It logs and deals with any error, and returns the appropriate bytes and response code for the `http_server`.
+	// commonReturn takes the body, err, and the data request Type which has been processed. It logs and deals with any error, and returns the appropriate bytes and response code for the `srvhttp`.
 	commonReturn := func(body []byte, err error) ([]byte, int) {
 		if err == nil {
 			return body, http.StatusOK
@@ -445,9 +479,8 @@ func DataRequest(
 		return []byte("Service Unavailable"), http.StatusServiceUnavailable
 	}
 
-	var err error
 	switch req.Type {
-	case http_server.TRConfig:
+	case srvhttp.TRConfig:
 		cdnName := opsConfig.Get().CdnName
 		if toSession == nil {
 			return commonReturn(nil, fmt.Errorf("Unable to connect to Traffic Ops"))
@@ -455,61 +488,53 @@ func DataRequest(
 		if cdnName == "" {
 			return commonReturn(nil, fmt.Errorf("No CDN Configured"))
 		}
-		return commonReturn(body, err)
-	case http_server.TRStateDerived:
-		body, err = peer.CrstatesMarshall(combinedStates.Get())
-		return commonReturn(body, err)
-	case http_server.TRStateSelf:
-		body, err = peer.CrstatesMarshall(localStates.Get())
-		return commonReturn(body, err)
-	case http_server.CacheStats:
+		return commonReturn(toSession.CRConfigRaw(cdnName))
+	case srvhttp.TRStateDerived:
+		return commonReturn(peer.CrstatesMarshall(combinedStates.Get()))
+	case srvhttp.TRStateSelf:
+		return commonReturn(peer.CrstatesMarshall(localStates.Get()))
+	case srvhttp.CacheStats:
 		filter, err := NewCacheStatFilter(req.Parameters, toData.Get().ServerTypes)
 		if err != nil {
 			handleErr(err)
 			return []byte(err.Error()), http.StatusBadRequest
 		}
-		body, err = cache.StatsMarshall(statHistory.Get(), filter, req.Parameters)
-		return commonReturn(body, err)
-	case http_server.DSStats:
+		return commonReturn(cache.StatsMarshall(statHistory.Get(), filter, req.Parameters))
+	case srvhttp.DSStats:
 		filter, err := NewDSStatFilter(req.Parameters, toData.Get().DeliveryServiceTypes)
 		if err != nil {
 			handleErr(err)
 			return []byte(err.Error()), http.StatusBadRequest
 		}
-		body, err = json.Marshal(dsStats.Get().JSON(filter, req.Parameters)) // TODO marshall beforehand, for performance? (test to see how often requests are made)
-		return commonReturn(body, err)
-	case http_server.EventLog:
-		body, err = json.Marshal(JSONEvents{Events: events.Get()})
-		return commonReturn(body, err)
-	case http_server.PeerStates:
+		// TODO marshall beforehand, for performance? (test to see how often requests are made)
+		return commonReturn(json.Marshal(dsStats.Get().JSON(filter, req.Parameters)))
+	case srvhttp.EventLog:
+		return commonReturn(json.Marshal(JSONEvents{Events: events.Get()}))
+	case srvhttp.PeerStates:
 		filter, err := NewPeerStateFilter(req.Parameters, toData.Get().ServerTypes)
 		if err != nil {
 			handleErr(err)
 			return []byte(err.Error()), http.StatusBadRequest
 		}
-
-		body, err = json.Marshal(createApiPeerStates(peerStates.Get(), filter, req.Parameters))
-		return commonReturn(body, err)
-	case http_server.StatSummary:
+		return commonReturn(json.Marshal(createAPIPeerStates(peerStates.Get(), filter, req.Parameters)))
+	case srvhttp.StatSummary:
 		return nil, http.StatusNotImplemented
-	case http_server.Stats:
-		body, err = getStats(staticAppData, healthPollInterval, lastHealthDurations.Get(), fetchCount.Get(), healthIteration.Get(), errorCount.Get())
-		return commonReturn(body, err)
-	case http_server.ConfigDoc:
+	case srvhttp.Stats:
+		return commonReturn(getStats(staticAppData, healthPollInterval, lastHealthDurations.Get(), fetchCount.Get(), healthIteration.Get(), errorCount.Get()))
+	case srvhttp.ConfigDoc:
 		opsConfigCopy := opsConfig.Get()
 		// if the password is blank, leave it blank, so callers can see it's missing.
 		if opsConfigCopy.Password != "" {
 			opsConfigCopy.Password = "*****"
 		}
-		body, err = json.Marshal(opsConfigCopy)
-		return commonReturn(body, err)
-	case http_server.APICacheCount: // TODO determine if this should use peerStates
+		return commonReturn(json.Marshal(opsConfigCopy))
+	case srvhttp.APICacheCount: // TODO determine if this should use peerStates
 		return []byte(strconv.Itoa(len(localStates.Get().Caches))), http.StatusOK
-	case http_server.APICacheAvailableCount:
+	case srvhttp.APICacheAvailableCount:
 		return []byte(strconv.Itoa(cacheAvailableCount(localStates.Get().Caches))), http.StatusOK
-	case http_server.APICacheDownCount:
-		return []byte(strconv.Itoa(cacheDownCount(localStates.Get().Caches))), http.StatusOK
-	case http_server.APIVersion:
+	case srvhttp.APICacheDownCount:
+		return []byte(strconv.Itoa(cacheDownCount(localStates.Get().Caches, monitorConfig.Get().TrafficServer))), http.StatusOK
+	case srvhttp.APIVersion:
 		s := "traffic_monitor-" + staticAppData.Version + "."
 		if len(staticAppData.GitRevision) > 6 {
 			s += staticAppData.GitRevision[:6]
@@ -517,13 +542,12 @@ func DataRequest(
 			s += staticAppData.GitRevision
 		}
 		return []byte(s), http.StatusOK
-	case http_server.APITrafficOpsURI:
+	case srvhttp.APITrafficOpsURI:
 		return []byte(opsConfig.Get().Url), http.StatusOK
-	case http_server.APICacheStates:
-		body, err = json.Marshal(createCacheStatuses(toData.Get().ServerTypes, statHistory.Get(),
-			lastHealthDurations.Get(), localStates.Get().Caches, lastStats.Get(), localCacheStatus))
-		return commonReturn(body, err)
-	case http_server.APIBandwidthKbps:
+	case srvhttp.APICacheStates:
+		return commonReturn(json.Marshal(createCacheStatuses(toData.Get().ServerTypes, statHistory.Get(),
+			lastHealthDurations.Get(), localStates.Get().Caches, lastStats.Get(), localCacheStatus)))
+	case srvhttp.APIBandwidthKbps:
 		serverTypes := toData.Get().ServerTypes
 		kbpsStats := lastStats.Get()
 		sum := float64(0.0)
@@ -534,7 +558,7 @@ func DataRequest(
 			sum += data.Bytes.PerSec / ds.BytesPerKilobit
 		}
 		return []byte(fmt.Sprintf("%f", sum)), http.StatusOK
-	case http_server.APIBandwidthCapacityKbps:
+	case srvhttp.APIBandwidthCapacityKbps:
 		statHistory := statHistory.Get()
 		cap := int64(0)
 		for _, results := range statHistory {
@@ -601,7 +625,7 @@ func createCacheStatuses(
 		}
 
 		var kbps *float64
-		lastStat, ok := lastStats.Caches[enum.CacheName(cacheName)]
+		lastStat, ok := lastStats.Caches[cacheName]
 		if !ok {
 			log.Warnf("cache not in last kbps cache %s\n", cacheName)
 		} else {
@@ -610,7 +634,7 @@ func createCacheStatuses(
 		}
 
 		var connections *int64
-		connectionsVal, ok := conns[enum.CacheName(cacheName)]
+		connectionsVal, ok := conns[cacheName]
 		if !ok {
 			log.Warnf("cache not in connections %s\n", cacheName)
 		} else {
@@ -618,12 +642,12 @@ func createCacheStatuses(
 		}
 
 		var status *string
-		statusVal, ok := localCacheStatus[enum.CacheName(cacheName)]
+		statusVal, ok := localCacheStatus[cacheName]
 		if !ok {
 			log.Warnf("cache not in statuses %s\n", cacheName)
 		} else {
 			statusString := statusVal.Status + " - "
-			if localCacheStatus[enum.CacheName(cacheName)].Available {
+			if localCacheStatus[cacheName].Available {
 				statusString += "available"
 			} else {
 				statusString += "unavailable"
@@ -632,7 +656,7 @@ func createCacheStatuses(
 		}
 
 		cacheTypeStr := string(cacheType)
-		statii[enum.CacheName(cacheName)] = CacheStatus{Type: &cacheTypeStr, LoadAverage: loadAverage, QueryTimeMilliseconds: queryTime, BandwidthKbps: kbps, ConnectionCount: connections, Status: status}
+		statii[cacheName] = CacheStatus{Type: &cacheTypeStr, LoadAverage: loadAverage, QueryTimeMilliseconds: queryTime, BandwidthKbps: kbps, ConnectionCount: connections, Status: status}
 	}
 	return statii
 }
@@ -658,7 +682,8 @@ func createCacheConnections(statHistory map[enum.CacheName][]cache.Result) map[e
 	return conns
 }
 
-func cacheDownCount(caches map[enum.CacheName]peer.IsAvailable) int {
+// cacheOfflineCount returns the total caches not available, including marked unavailable, status offline, and status admin_down
+func cacheOfflineCount(caches map[enum.CacheName]peer.IsAvailable) int {
 	count := 0
 	for _, available := range caches {
 		if !available.IsAvailable {
@@ -668,15 +693,26 @@ func cacheDownCount(caches map[enum.CacheName]peer.IsAvailable) int {
 	return count
 }
 
+// cacheAvailableCount returns the total caches available, including marked available and status online
 func cacheAvailableCount(caches map[enum.CacheName]peer.IsAvailable) int {
-	return len(caches) - cacheDownCount(caches)
+	return len(caches) - cacheOfflineCount(caches)
+}
+
+// cacheOfflineCount returns the total reported caches marked down, excluding status offline and admin_down.
+func cacheDownCount(caches map[enum.CacheName]peer.IsAvailable, toServers map[string]to.TrafficServer) int {
+	count := 0
+	for cache, available := range caches {
+		if !available.IsAvailable && enum.CacheStatusFromString(toServers[string(cache)].Status) == enum.CacheStatusReported {
+			count++
+		}
+	}
+	return count
 }
 
-func createApiPeerStates(peerStates map[enum.TrafficMonitorName]peer.Crstates, filter *PeerStateFilter, params url.Values) ApiPeerStates {
-	apiPeerStates := ApiPeerStates{
-		Peers:       map[enum.TrafficMonitorName]map[enum.CacheName][]CacheState{},
-		QueryParams: http_server.ParametersStr(params),
-		DateStr:     http_server.DateStr(time.Now()),
+func createAPIPeerStates(peerStates map[enum.TrafficMonitorName]peer.Crstates, filter *PeerStateFilter, params url.Values) APIPeerStates {
+	apiPeerStates := APIPeerStates{
+		CommonAPIData: srvhttp.GetCommonAPIData(params, time.Now()),
+		Peers:         map[enum.TrafficMonitorName]map[enum.CacheName][]CacheState{},
 	}
 
 	for peer, state := range peerStates {
@@ -698,6 +734,7 @@ func createApiPeerStates(peerStates map[enum.TrafficMonitorName]peer.Crstates, f
 	return apiPeerStates
 }
 
+// Stats contains statistics data about this running app. Designed to be returned via an API endpoint.
 type Stats struct {
 	MaxMemoryMB         uint64 `json:"Max Memory (MB)"`
 	GitRevision         string `json:"git-revision"`

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/manager/dsstats.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/manager/dsstats.go b/traffic_monitor/experimental/traffic_monitor/manager/dsstats.go
index ae273d8..23a3fef 100644
--- a/traffic_monitor/experimental/traffic_monitor/manager/dsstats.go
+++ b/traffic_monitor/experimental/traffic_monitor/manager/dsstats.go
@@ -1,31 +1,56 @@
 package manager
 
+/*
+ * 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.
+ */
+
+
 import (
-	ds "github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/deliveryservice"
-	dsdata "github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/deliveryservicedata"
+	ds "github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/deliveryservice"
+	dsdata "github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/deliveryservicedata"
 	"sync"
 )
 
+// DSStatsThreadsafe wraps a deliveryservice.Stats object to be safe for multiple reader goroutines and a single writer.
 type DSStatsThreadsafe struct {
 	dsStats *ds.Stats
 	m       *sync.RWMutex
 }
 
+// DSStatsReader permits reading of a dsdata.Stats object, but not writing. This is designed so a Stats object can safely be passed to multiple goroutines, without worry one may unsafely write.
 type DSStatsReader interface {
 	Get() dsdata.StatsReadonly
 }
 
+// NewDSStatsThreadsafe returns a deliveryservice.Stats object wrapped to be safe for multiple readers and a single writer.
 func NewDSStatsThreadsafe() DSStatsThreadsafe {
 	s := ds.NewStats()
 	return DSStatsThreadsafe{m: &sync.RWMutex{}, dsStats: &s}
 }
 
+// Get returns a Stats object safe for reading by multiple goroutines
 func (o *DSStatsThreadsafe) Get() dsdata.StatsReadonly {
 	o.m.RLock()
 	defer o.m.RUnlock()
 	return *o.dsStats
 }
 
+// Set sets the internal Stats object. This MUST NOT be called by multiple goroutines.
 func (o *DSStatsThreadsafe) Set(newDsStats ds.Stats) {
 	o.m.Lock()
 	*o.dsStats = newDsStats

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/be5ab888/traffic_monitor/experimental/traffic_monitor/manager/events.go
----------------------------------------------------------------------
diff --git a/traffic_monitor/experimental/traffic_monitor/manager/events.go b/traffic_monitor/experimental/traffic_monitor/manager/events.go
index 19e4f5d..0a35783 100644
--- a/traffic_monitor/experimental/traffic_monitor/manager/events.go
+++ b/traffic_monitor/experimental/traffic_monitor/manager/events.go
@@ -1,11 +1,32 @@
 package manager
 
+/*
+ * 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.
+ */
+
+
 import (
 	"sync"
 
-	"github.com/Comcast/traffic_control/traffic_monitor/experimental/traffic_monitor/enum"
+	"github.com/apache/incubator-trafficcontrol/traffic_monitor/experimental/traffic_monitor/enum"
 )
 
+// Event represents an event change in aggregated data. For example, a cache being marked as unavailable.
 type Event struct {
 	Index       uint64         `json:"index"`
 	Time        int64          `json:"time"`
@@ -16,6 +37,7 @@ type Event struct {
 	Available   bool           `json:"isAvailable"`
 }
 
+// EventsThreadsafe provides safe access for multiple goroutines readers and a single writer to a stored Events slice.
 type EventsThreadsafe struct {
 	events    *[]Event
 	m         *sync.RWMutex
@@ -25,17 +47,17 @@ type EventsThreadsafe struct {
 
 func copyEvents(a []Event) []Event {
 	b := make([]Event, len(a), len(a))
-	for i, v := range a {
-		b[i] = v
-	}
+	copy(b, a)
 	return b
 }
 
+// NewEventsThreadsafe creates a new single-writer-multiple-reader Threadsafe object
 func NewEventsThreadsafe(maxEvents uint64) EventsThreadsafe {
 	i := uint64(0)
 	return EventsThreadsafe{m: &sync.RWMutex{}, events: &[]Event{}, nextIndex: &i, max: maxEvents}
 }
 
+// Get returns the internal slice of Events for reading. This MUST NOT be modified. If modification is necessary, copy the slice.
 func (o *EventsThreadsafe) Get() []Event {
 	o.m.RLock()
 	defer o.m.RUnlock()