Skip to content

Commit

Permalink
Make inner http client configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
lampajr committed Apr 24, 2024
1 parent 7bdec7f commit 1616aeb
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 30 deletions.
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ build: generate vet lint ## Build golang pkg

##@ Example

.PHONY: run-example
run-example: ## Run basic example
go run examples/basic_example.go
.PHONY: run-basic-example
run-basic-example: ## Run basic example
go run examples/basic/basic_example.go

.PHONY: run-read-only-example
run-read-only-example: ## Run read-only example
go run examples/readonly/read_only_example.go
8 changes: 5 additions & 3 deletions examples/basic_example.go → examples/basic/basic_example.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func Of[E any](e E) *E {
return &e
}

// this will setup all data variables
// This will setup all data variables
func init() {
log.Printf("setting up data")

Expand Down Expand Up @@ -156,7 +156,10 @@ func deleteAll(client *horreum.HorreumClient) {
}

func main() {
client, err := horreum.NewHorreumClient("http://localhost:8080", &username, &password)
client, err := horreum.NewHorreumClient("http://localhost:8080", &horreum.HorreumCredentials{
Username: &username,
Password: &password,
}, nil)
if err != nil {
log.Fatalf("error creating Horreum client: %s", err.Error())
}
Expand Down Expand Up @@ -185,5 +188,4 @@ func main() {
if getRuns, _ := client.RawClient.Api().Run().List().Get(ctx, nil); *getRuns.GetTotal() != int64(1) {
log.Fatalf("expected 1 run in the server")
}

}
76 changes: 76 additions & 0 deletions examples/readonly/read_only_example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package main

import (
"context"
"crypto/tls"
"log"
"net/http"
"time"

"github.com/hyperfoil/horreum-client-golang/pkg/horreum"
abstractions "github.com/microsoft/kiota-abstractions-go"
)

var (
ctx = context.Background()
baseUrl = "http://localhost:8080"
username = "user"
password = "secret"

// assertions
enableAssertion = true
expectedSchemasCount = 2
expectedTestsCount = 1
)

// Of returns a pointer to the provided literal/const input
func Of[E any](e E) *E {
return &e
}

func main() {
httpClient := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
Timeout: time.Second * 100,
}
parentTransport, _ := http.DefaultTransport.(*http.Transport)
parentTransport.ForceAttemptHTTP2 = true
parentTransport.DisableCompression = true
parentTransport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
}

client, err := horreum.NewHorreumClient(baseUrl,
&horreum.HorreumCredentials{
Username: &username,
Password: &password,
},
&horreum.ClientConfiguration{
HttpClient: httpClient,
ParentTransport: parentTransport,
UseDefaultMiddlewares: true,
Options: []abstractions.RequestOption{},
},
)
if err != nil {
log.Fatalf("error creating Horreum client: %s", err.Error())
}

clientVersion := client.Version()
serverVersion, err := client.RawClient.Api().Config().Version().Get(ctx, nil)
if err != nil {
log.Fatalf("error fetching Horreum server version: %s", err.Error())
}

log.Printf("Running client %s against server %s", clientVersion, *serverVersion.GetVersion())

// assert data into Horreum server
if getSchemas, _ := client.RawClient.Api().Schema().Get(ctx, nil); enableAssertion && *getSchemas.GetCount() != int64(2) {
log.Fatalf("expected %d schemas in the server", expectedSchemasCount)
}
if getTests, _ := client.RawClient.Api().Test().Get(ctx, nil); enableAssertion && *getTests.GetCount() != int64(1) {
log.Fatalf("expected %d test in the server", expectedTestsCount)
}
}
35 changes: 35 additions & 0 deletions pkg/horreum/configs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package horreum

import (
"net/http"

abstractions "github.com/microsoft/kiota-abstractions-go"
)

type HorreumCredentials struct {
Username *string
Password *string
}

func NewDefaultHorreumCredentials() HorreumCredentials {
return HorreumCredentials{
Username: nil,
Password: nil,
}
}

type ClientConfiguration struct {
HttpClient *http.Client
ParentTransport http.RoundTripper
UseDefaultMiddlewares bool
Options []abstractions.RequestOption
}

func NewDefaultClientConfiguration() ClientConfiguration {
return ClientConfiguration{
HttpClient: nil,
ParentTransport: nil,
UseDefaultMiddlewares: true,
Options: []abstractions.RequestOption{},
}
}
65 changes: 44 additions & 21 deletions pkg/horreum/horreum.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"context"
"fmt"

nethttp "net/http"

"github.com/hyperfoil/horreum-client-golang/pkg/raw_client"
abstractions "github.com/microsoft/kiota-abstractions-go"
"github.com/microsoft/kiota-abstractions-go/authentication"
http "github.com/microsoft/kiota-http-go"

Expand All @@ -15,9 +18,9 @@ import (
var version string

type HorreumClient struct {
baseUrl string
username *string
password *string
baseUrl string
credentials *HorreumCredentials
clientConfig *ClientConfiguration

RawClient *raw_client.HorreumRawClient
AuthProvder authentication.AuthenticationProvider
Expand All @@ -41,34 +44,54 @@ func setupAuthProvider(baseUrl string, username string, password string) (authen
return NewKeycloakAccessProvider(config, username, password)
}

func NewHorreumClient(baseUrl string, username *string, password *string) (*HorreumClient, error) {
func NewHorreumClient(baseUrl string, credentials *HorreumCredentials, clientConfig *ClientConfiguration) (*HorreumClient, error) {
client := &HorreumClient{
baseUrl: baseUrl,
username: username,
password: password,
baseUrl: baseUrl,
credentials: credentials,
clientConfig: clientConfig,

// By default, set auth provider to anonymous one
AuthProvder: &authentication.AnonymousAuthenticationProvider{},
}

if username != nil && password != nil {
provider, err := setupAuthProvider(baseUrl, *username, *password)
if err != nil {
return nil, fmt.Errorf("error setting up keycloak provider: %w", err)
if credentials != nil {
if credentials.Username != nil && credentials.Password != nil {
provider, err := setupAuthProvider(baseUrl, *credentials.Username, *credentials.Password)
if err != nil {
return nil, fmt.Errorf("error setting up keycloak provider: %w", err)
}
client.AuthProvder = authentication.NewBaseBearerTokenAuthenticationProvider(provider)
} else if credentials.Password != nil {
return nil, fmt.Errorf("providing password without username, have you missed something?")
}
client.AuthProvder = authentication.NewBaseBearerTokenAuthenticationProvider(provider)
} else if password != nil {
return nil, fmt.Errorf("providing password without username, have you missed something?")
} else {
// anonymous authentication
client.AuthProvder = &authentication.AnonymousAuthenticationProvider{}
}

// Disable gzip compression
// To avoid "HTTP 400 Bad Request Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens"
compressOpt := http.NewCompressionOptions(false)
middlewares, err := http.GetDefaultMiddlewaresWithOptions(&compressOpt)
compressOption := http.NewCompressionOptions(false)
middlewareOptions := []abstractions.RequestOption{
&compressOption,
}
// Add additional middleware options if provided
if clientConfig != nil && len(clientConfig.Options) > 0 {
middlewareOptions = append(middlewareOptions, clientConfig.Options...)
}

// Create default middlewares with provided options
middlewares, err := http.GetDefaultMiddlewaresWithOptions(middlewareOptions...)
if err != nil {
return nil, fmt.Errorf("error creating default middlewares with compression disabled")
return nil, fmt.Errorf("error creating default middlewares with custom options: %w", err)
}
httpClient := http.GetDefaultClient(middlewares...)

var httpClient *nethttp.Client
if clientConfig != nil && clientConfig.HttpClient != nil && clientConfig.UseDefaultMiddlewares {
httpClient = clientConfig.HttpClient
// Set middlewares
httpClient.Transport = http.NewCustomTransportWithParentTransport(clientConfig.ParentTransport, middlewares...)
} else {
httpClient = http.GetDefaultClient(middlewares...)
}

adapter, err := http.NewNetHttpRequestAdapterWithParseNodeFactoryAndSerializationWriterFactoryAndHttpClient(client.AuthProvder, nil, nil, httpClient)
if err != nil {
return nil, fmt.Errorf("error creating client adapter: %w", err)
Expand Down
5 changes: 4 additions & 1 deletion pkg/horreum/horreum_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ func setupAnonymousClient(t *testing.T) (*assert.Assertions, *HorreumClient) {
}

func setupAuthenticatedClient(t *testing.T) (*assert.Assertions, *HorreumClient) {
client, err := NewHorreumClient("http://localhost:8080", &username, &password)
client, err := NewHorreumClient("http://localhost:8080", &HorreumCredentials{
Username: &username,
Password: &password,
}, nil)
assertion := assert.New(t)
assertion.Nil(err)

Expand Down
10 changes: 8 additions & 2 deletions pkg/horreum/horreum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ func setup(t *testing.T) (*assert.Assertions, *HorreumClient) {
}

func TestMissingMissingPasswordWithUsername(t *testing.T) {
_, err := NewHorreumClient("http://localhost:8080", nil, &password)
_, err := NewHorreumClient("http://localhost:8080", &HorreumCredentials{
Username: nil,
Password: &password,
}, nil)
assert.NotNil(t, err)
assert.Equal(t, "providing password without username, have you missed something?", err.Error())
}

func TestAuthProviderSetupFailure(t *testing.T) {
_, err := NewHorreumClient("http://localhost:9999", &username, &password)
_, err := NewHorreumClient("http://localhost:9999", &HorreumCredentials{
Username: &username,
Password: &password,
}, nil)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "error setting up keycloak provider")
assert.Contains(t, err.Error(), "error retrieving keycloak configuration")
Expand Down

0 comments on commit 1616aeb

Please sign in to comment.