Skip to content

Commit

Permalink
added priority to fetch definition (wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
yneuma committed Oct 12, 2016
1 parent a61984f commit d83ec9e
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 2 deletions.
21 changes: 21 additions & 0 deletions composition/composition_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"
"strconv"
"strings"
"sort"
)

// A ContentFetcherFactory returns a configured fetch job for a request
Expand Down Expand Up @@ -54,6 +55,17 @@ func (agg *CompositionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
// fetch all contents
results := fetcher.WaitForResults()


priorityExists := hasPrioritySetting(results)
if (priorityExists) {
sort.Sort(FetchResults(results))
//TODO hier oder anders wo
// für alle fragmente in aufsteigender prioritätsreihenfolge:
// extrahiere alle meta-tags (inkl. entfernen) und schreibe sie in eine map
// fragmente mit höherer Priorität können werte mit gleichem key überschreiben.
// schreibe die meta-tags in den head des letzten fragments
}

mergeContext := agg.contentMergerFactory(fetcher.MetaJSON())

for _, res := range results {
Expand Down Expand Up @@ -143,3 +155,12 @@ func getHostFromRequest(r *http.Request) string {
}
return host
}

func hasPrioritySetting(results []*FetchResult) bool {
for _, res := range results {
if(res.Def.Priority > 0){
return true
}
}
return false
}
14 changes: 14 additions & 0 deletions composition/content_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ type FetchResult struct {
Hash string // the hash of the FetchDefinition
}

//Provide implementation for sorting FetchResults by priority with sort.Sort
type FetchResults []*FetchResult

func (fr FetchResults) Len() int {
return len(fr)
}
func (fr FetchResults) Swap(i, j int) {
fr[i], fr[j] = fr[j], fr[i]
}
func (fr FetchResults) Less(i, j int) bool {
return fr[i].Def.Priority < fr[j].Def.Priority
}


// ContentFetcher is a type, which can fetch a set of Content pages in parallel.
type ContentFetcher struct {
activeJobs sync.WaitGroup
Expand Down
21 changes: 21 additions & 0 deletions composition/content_fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"testing"
"time"
"sort"
)

func Test_ContentFetcher_FetchingWithDependency(t *testing.T) {
Expand Down Expand Up @@ -74,3 +75,23 @@ func getFetchDefinitionMock(ctrl *gomock.Controller, loaderMock *MockContentLoad

return fd
}

func Test_ContentFetchResultPrioritySort(t *testing.T) {
a := assert.New(t)

barFd := NewFetchDefinitionWithPriority("/bar", 30)
fooFd := NewFetchDefinitionWithPriority("/foo", 10)
bazzFd := NewFetchDefinitionWithPriority("/bazz", 5)

results := []*FetchResult{{Def: barFd}, {Def: fooFd}, {Def: bazzFd}}

a.Equal(30, results[0].Def.Priority)
a.Equal(10, results[1].Def.Priority)
a.Equal(5, results[2].Def.Priority)

sort.Sort(FetchResults(results))

a.Equal(5, results[0].Def.Priority)
a.Equal(10, results[1].Def.Priority)
a.Equal(30, results[2].Def.Priority)
}
34 changes: 32 additions & 2 deletions composition/fetch_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ var ForwardResponseHeaders = []string{
const (
DefaultTimeout time.Duration = 10 * time.Second
FileURLPrefix = "file://"
DefaultPriority = 0
)

// FetchDefinition is a descriptor for fetching Content from an endpoint.
Expand All @@ -69,14 +70,23 @@ type FetchDefinition struct {
CacheStrategy CacheStrategy
ServiceDiscoveryActive bool
ServiceDiscovery servicediscovery.ServiceDiscovery
Priority int
}

// Creates a fetch definition
func NewFetchDefinition(url string) *FetchDefinition {
return NewFetchDefinitionWithResponseProcessor(url, nil)
return NewFetchDefinitionWithResponseProcessorAndPriority(url, nil, DefaultPriority)
}

func NewFetchDefinitionWithPriority(url string, priority int) *FetchDefinition {
return NewFetchDefinitionWithResponseProcessorAndPriority(url, nil, priority)
}

func NewFetchDefinitionWithErrorHandler(url string, errHandler ErrorHandler) *FetchDefinition {
return NewFetchDefinitionWithErrorHandlerAndPriority(url, errHandler, DefaultPriority)
}

func NewFetchDefinitionWithErrorHandlerAndPriority(url string, errHandler ErrorHandler, priority int) *FetchDefinition {
if errHandler == nil {
errHandler = NewDefaultErrorHandler()
}
Expand All @@ -88,11 +98,18 @@ func NewFetchDefinitionWithErrorHandler(url string, errHandler ErrorHandler) *Fe
Method: "GET",
ErrHandler: errHandler,
CacheStrategy: cache.DefaultCacheStrategy,
Priority: priority,
}
}

// If a ResponseProcessor-Implementation is given it can be used to change the response before composition
func NewFetchDefinitionWithResponseProcessor(url string, rp ResponseProcessor) *FetchDefinition {
return NewFetchDefinitionWithResponseProcessorAndPriority(url, rp, DefaultPriority)
}

// If a ResponseProcessor-Implementation is given it can be used to change the response before composition
// Priority is used to determine which property from which head has to be taken by collision of multiple fetches
func NewFetchDefinitionWithResponseProcessorAndPriority(url string, rp ResponseProcessor, priority int) *FetchDefinition {
return &FetchDefinition{
URL: url,
Timeout: DefaultTimeout,
Expand All @@ -102,20 +119,32 @@ func NewFetchDefinitionWithResponseProcessor(url string, rp ResponseProcessor) *
RespProc: rp,
ErrHandler: NewDefaultErrorHandler(),
CacheStrategy: cache.DefaultCacheStrategy,
Priority: priority,
}
}

// NewFetchDefinitionFromRequest creates a fetch definition
// from the request path, but replaces the scheme, host and port with the provided base url
func NewFetchDefinitionFromRequest(baseUrl string, r *http.Request) *FetchDefinition {
return NewFetchDefinitionWithResponseProcessorFromRequest(baseUrl, r, nil)
return NewFetchDefinitionWithResponseProcessorAndPriorityFromRequest(baseUrl, r, nil, DefaultPriority)
}

// NewFetchDefinitionFromRequest creates a fetch definition
// from the request path, but replaces the scheme, host and port with the provided base url
func NewFetchDefinitionWithPriorityFromRequest(baseUrl string, r *http.Request, priority int) *FetchDefinition {
return NewFetchDefinitionWithResponseProcessorAndPriorityFromRequest(baseUrl, r, nil, priority)
}

// NewFetchDefinitionFromRequest creates a fetch definition
// from the request path, but replaces the scheme, host and port with the provided base url
// If a ResponseProcessor-Implementation is given it can be used to change the response before composition
// Only those headers, defined in ForwardRequestHeaders are copied to the FetchDefinition.
func NewFetchDefinitionWithResponseProcessorFromRequest(baseUrl string, r *http.Request, rp ResponseProcessor) *FetchDefinition {
return NewFetchDefinitionWithResponseProcessorAndPriorityFromRequest(baseUrl, r, rp, DefaultPriority)
}

// NewFetchDefinitionWithResponseProcessorFromRequest with priority setting for head property collision handling
func NewFetchDefinitionWithResponseProcessorAndPriorityFromRequest(baseUrl string, r *http.Request, rp ResponseProcessor, priority int) *FetchDefinition {
if strings.HasSuffix(baseUrl, "/") {
baseUrl = baseUrl[:len(baseUrl)-1]
}
Expand All @@ -138,6 +167,7 @@ func NewFetchDefinitionWithResponseProcessorFromRequest(baseUrl string, r *http.
Required: true,
RespProc: rp,
ErrHandler: NewDefaultErrorHandler(),
Priority: priority,
}
}

Expand Down
39 changes: 39 additions & 0 deletions composition/fetch_definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,42 @@ func Test_FetchDefinition_use_DefaultErrorHandler_if_not_set(t *testing.T) {
fd := NewFetchDefinitionWithErrorHandler("http://upstream:8080/", nil)
a.Equal(NewDefaultErrorHandler(), fd.ErrHandler)
}


func Test_FetchDefinition_NewFunctions_have_default_priority(t *testing.T) {
a := assert.New(t)
fd1 := NewFetchDefinition("foo")
fd2 := NewFetchDefinitionWithErrorHandler("baa", nil)
fd3 := NewFetchDefinitionWithResponseProcessor("blub", nil)

r, err := http.NewRequest("POST", "https://example.com/content?foo=bar", nil)
a.NoError(err)

fd4 := NewFetchDefinitionWithResponseProcessorFromRequest("bla", r, nil)


a.Equal(fd1.Priority, DefaultPriority)
a.Equal(fd2.Priority, DefaultPriority)
a.Equal(fd3.Priority, DefaultPriority)
a.Equal(fd4.Priority, DefaultPriority)
}

func Test_FetchDefinition_NewFunctions_have_parameter_priority(t *testing.T) {
a := assert.New(t)
fd1 := NewFetchDefinitionWithPriority("foo", 42)
fd2 := NewFetchDefinitionWithErrorHandlerAndPriority("baa", nil, 54)
fd3 := NewFetchDefinitionWithResponseProcessorAndPriority("blub", nil, 74)


r, err := http.NewRequest("POST", "https://example.com/content?foo=bar", nil)
a.NoError(err)

fd4 := NewFetchDefinitionWithResponseProcessorAndPriorityFromRequest("bla", r, nil, 90)
fd5 := NewFetchDefinitionWithPriorityFromRequest("faa", r, 2014)

a.Equal(fd1.Priority, 42)
a.Equal(fd2.Priority, 54)
a.Equal(fd3.Priority, 74)
a.Equal(fd4.Priority, 90)
a.Equal(fd5.Priority, 2014)
}

0 comments on commit d83ec9e

Please sign in to comment.