提交 3ec11a63 编写于 作者: R Ray Tsang 提交者: Piotr Bryk

Added initial filter capability. (#1515)

* Added initial filter capability.

* Removed fmt.Printf
上级 a460bad6
......@@ -1617,6 +1617,10 @@ func parsePaginationPathParameter(request *restful.Request) *dataselect.Paginati
return dataselect.NewPaginationQuery(int(itemsPerPage), int(page-1))
}
func parseFilterPathParameter(request *restful.Request) *dataselect.FilterQuery {
return dataselect.NewFilterQuery(strings.Split(request.QueryParameter("filterby"), ","))
}
// Parses query parameters of the request and returns a SortQuery object
func parseSortPathParameter(request *restful.Request) *dataselect.SortQuery {
return dataselect.NewSortQuery(strings.Split(request.QueryParameter("sortby"), ","))
......@@ -1650,6 +1654,7 @@ func parseMetricPathParameter(request *restful.Request) *dataselect.MetricQuery
func parseDataSelectPathParameter(request *restful.Request) *dataselect.DataSelectQuery {
paginationQuery := parsePaginationPathParameter(request)
sortQuery := parseSortPathParameter(request)
filterQuery := parseFilterPathParameter(request)
metricQuery := parseMetricPathParameter(request)
return dataselect.NewDataSelectQuery(paginationQuery, sortQuery, metricQuery)
return dataselect.NewDataSelectQuery(paginationQuery, sortQuery, filterQuery, metricQuery)
}
......@@ -109,6 +109,32 @@ func (self *DataSelector) Sort() *DataSelector {
return self
}
// Filter the data inside as instructed by DataSelectQuery and returns itself to allow method chaining.
func (self *DataSelector) Filter() *DataSelector {
filteredList := []DataCell{}
for _, c := range self.GenericDataList {
matches := true
for _, filterBy := range self.DataSelectQuery.FilterQuery.FilterByList {
v := c.GetProperty(filterBy.Property)
if v == nil {
matches = false
continue
}
if filterBy.Value.Compare(v) != 0 {
matches = false
continue
}
}
if matches {
filteredList = append(filteredList, c)
}
}
self.GenericDataList = filteredList
return self
}
// GetCumulativeMetrics downloads and aggregates metrics for data cells currently present in self.GenericDataList as instructed
// by MetricQuery and inserts resulting MetricPromises to self.CumulativeMetricsPromises.
func (self *DataSelector) GetCumulativeMetrics(heapsterClient *client.HeapsterClient) *DataSelector {
......@@ -184,3 +210,18 @@ func GenericDataSelectWithMetrics(dataList []DataCell, dsQuery *DataSelectQuery,
processed := SelectableData.Sort().GetCumulativeMetrics(heapsterClient).Paginate()
return processed.GenericDataList, processed.CumulativeMetricsPromises
}
func GenericDataSelectWithFilterAndMetrics(dataList []DataCell, dsQuery *DataSelectQuery,
cachedResources *CachedResources, heapsterClient *client.HeapsterClient) ([]DataCell, metric.MetricPromises, int) {
SelectableData := DataSelector{
GenericDataList: dataList,
DataSelectQuery: dsQuery,
CachedResources: cachedResources,
}
// Pipeline is Filter -> Sort -> CollectMetrics -> Paginate
filtered := SelectableData.Filter()
filteredTotal := len(filtered.GenericDataList)
processed := filtered.Sort().GetCumulativeMetrics(heapsterClient).Paginate()
return processed.GenericDataList, processed.CumulativeMetricsPromises, filteredTotal
}
......@@ -25,8 +25,8 @@ import (
type DataSelectQuery struct {
PaginationQuery *PaginationQuery
SortQuery *SortQuery
// Filter *FilterQuery
MetricQuery *MetricQuery
FilterQuery *FilterQuery
MetricQuery *MetricQuery
}
var NoMetrics = NewMetricQuery(nil, nil)
......@@ -72,23 +72,37 @@ var NoSort = &SortQuery{
SortByList: []SortBy{},
}
type FilterQuery struct {
FilterByList []FilterBy
}
type FilterBy struct {
Property PropertyName
Value ComparableValue
}
var NoFilter = &FilterQuery{
FilterByList: []FilterBy{},
}
// NoDataSelect is an option for no data select (same data will be returned).
var NoDataSelect = NewDataSelectQuery(NoPagination, NoSort, NoMetrics)
var NoDataSelect = NewDataSelectQuery(NoPagination, NoSort, NoFilter, NoMetrics)
// StdMetricsDataSelect does not perform any data select, just downloads standard metrics.
var StdMetricsDataSelect = NewDataSelectQuery(NoPagination, NoSort, StandardMetrics)
var StdMetricsDataSelect = NewDataSelectQuery(NoPagination, NoSort, NoFilter, StandardMetrics)
// DefaultDataSelect downloads first 10 items from page 1 with no sort and no metrics.
var DefaultDataSelect = NewDataSelectQuery(DefaultPagination, NoSort, NoMetrics)
var DefaultDataSelect = NewDataSelectQuery(DefaultPagination, NoSort, NoFilter, NoMetrics)
// DefaultDataSelectWithMetrics downloads first 10 items from page 1 with no sort. Also downloads and includes standard metrics.
var DefaultDataSelectWithMetrics = NewDataSelectQuery(DefaultPagination, NoSort, StandardMetrics)
var DefaultDataSelectWithMetrics = NewDataSelectQuery(DefaultPagination, NoSort, NoFilter, StandardMetrics)
// NewDataSelectQuery creates DataSelectQuery object from simpler data select queries.
func NewDataSelectQuery(paginationQuery *PaginationQuery, sortQuery *SortQuery, graphQuery *MetricQuery) *DataSelectQuery {
func NewDataSelectQuery(paginationQuery *PaginationQuery, sortQuery *SortQuery, filterQuery *FilterQuery, graphQuery *MetricQuery) *DataSelectQuery {
return &DataSelectQuery{
PaginationQuery: paginationQuery,
SortQuery: sortQuery,
FilterQuery: filterQuery,
MetricQuery: graphQuery,
}
}
......@@ -128,3 +142,26 @@ func NewSortQuery(sortByListRaw []string) *SortQuery {
SortByList: sortByList,
}
}
// NewFilterQuery takes raw filter options list and returns FilterQuery object. For example:
// ["parameter1", "value1", "parameter2", "value2"] - means that the data should be filtered by
// parameter1 equals value1 and parameter2 equals value2
func NewFilterQuery(filterByListRaw []string) *FilterQuery {
if filterByListRaw == nil || len(filterByListRaw)%2 == 1 {
return NoFilter
}
filterByList := []FilterBy{}
for i := 0; i+1 < len(filterByListRaw); i += 2 {
propertyName := filterByListRaw[i]
propertyValue := filterByListRaw[i+1]
filterBy := FilterBy{
Property: PropertyName(propertyName),
Value: StdComparableString(propertyValue),
}
// Add to the filter options.
filterByList = append(filterByList, filterBy)
}
return &FilterQuery{
FilterByList: filterByList,
}
}
......@@ -23,4 +23,5 @@ const (
NameProperty = "name"
CreationTimestampProperty = "creationTimestamp"
NamespaceProperty = "namespace"
StatusProperty = "status"
)
......@@ -81,6 +81,8 @@ func (self PodCell) GetProperty(name dataselect.PropertyName) dataselect.Compara
return dataselect.StdComparableTime(self.ObjectMeta.CreationTimestamp.Time)
case dataselect.NamespaceProperty:
return dataselect.StdComparableString(self.ObjectMeta.Namespace)
case dataselect.StatusProperty:
return dataselect.StdComparableString(self.Status.Phase)
default:
// if name is not supported then just return a constant dummy value, sort will have no effect.
return nil
......
......@@ -108,15 +108,15 @@ func CreatePodList(pods []api.Pod, events []api.Event, dsQuery *dataselect.DataS
metrics := <-channels.PodMetrics.MetricsByPod
podList := PodList{
Pods: make([]Pod, 0),
ListMeta: common.ListMeta{TotalItems: len(pods)},
Pods: make([]Pod, 0),
}
cache := &dataselect.CachedResources{Pods: pods}
podCells, cumulativeMetricsPromises := dataselect.GenericDataSelectWithMetrics(toCells(pods), dsQuery,
podCells, cumulativeMetricsPromises, filteredTotal := dataselect.GenericDataSelectWithFilterAndMetrics(toCells(pods), dsQuery,
cache, &heapsterClient)
pods = fromCells(podCells)
podList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, pod := range pods {
warnings := event.GetPodsEventWarnings(events, []api.Pod{pod})
......
......@@ -108,7 +108,7 @@ func GetWorkloadsFromChannels(channels *common.ResourceChannels,
go func() {
podList, err := pod.GetPodListFromChannels(channels,
dataselect.NewDataSelectQuery(dataselect.DefaultPagination, dataselect.NoSort, metricQuery),
dataselect.NewDataSelectQuery(dataselect.DefaultPagination, dataselect.NoSort, dataselect.NoFilter, metricQuery),
heapsterClient)
errChan <- err
podChan <- podList
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册