Skip to content

Commit

Permalink
Merge pull request #10 from Piszmog/develop
Browse files Browse the repository at this point in the history
Cleanup errors, update dependencies, slight changes to apis
  • Loading branch information
Piszmog authored Jan 22, 2020
2 parents 856b394 + cc78f48 commit 0666a8b
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 35 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"fmt"
"github.com/Piszmog/cfservices"
"github.com/Piszmog/cloudconfigclient"
"net/http"
)

type File struct {
Expand All @@ -46,9 +47,9 @@ type Example struct {

func main() {
// To create a Client for a locally running Spring Config Server
configClient, err := cloudconfigclient.CreateLocalClientFromEnv()
configClient, err := cloudconfigclient.CreateLocalClientFromEnv(&http.Client{})
// Or
configClient, err := cloudconfigclient.CreateLocalClient([]string{"http://localhost:8888"})
configClient, err := cloudconfigclient.CreateLocalClient(&http.Client{}, []string{"http://localhost:8888"})
// or to create a Client for a Spring Config Server in Cloud Foundry
configClient, err := cloudconfigclient.CreateCloudClient()
// or to create a Client for a Spring Config Server with OAuth2
Expand Down
14 changes: 9 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"github.com/Piszmog/cloudconfigclient/net"
"io/ioutil"
"net/http"
)

Expand Down Expand Up @@ -45,17 +46,20 @@ func (client Client) Get(uriVariables ...string) (resp *http.Response, err error
func getResource(client CloudClient, dest interface{}, uriVariables ...string) error {
resp, err := client.Get(uriVariables...)
if err != nil {
return fmt.Errorf("failed to retrieve application configurations: %w", err)
return err
}
defer resp.Body.Close()
defer closeResource(resp.Body)
if resp.StatusCode == 404 {
return &NotFoundError{}
}
if resp.StatusCode != 200 {
return fmt.Errorf("server responded with status code %d", resp.StatusCode)
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read body with status code %d: %w", resp.StatusCode, err)
}
return fmt.Errorf("server responded with status code %d and body %s", resp.StatusCode, b)
}
decoder := json.NewDecoder(resp.Body)
if err := decoder.Decode(dest); err != nil {
if err := json.NewDecoder(resp.Body).Decode(dest); err != nil {
return fmt.Errorf("failed to decode response from url: %w", err)
}
return nil
Expand Down
3 changes: 2 additions & 1 deletion configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/Piszmog/cloudconfigclient/net"
)

var notFoundError *NotFoundError

// Source is the application's source configurations. It con contain zero to n number of property sources.
type Source struct {
Name string `json:"name"`
Expand Down Expand Up @@ -35,7 +37,6 @@ func (c ConfigClient) GetConfiguration(applicationName string, profiles []string
var source Source
for _, client := range c.Clients {
if err := getResource(client, &source, applicationName, net.JoinProfiles(profiles)); err != nil {
var notFoundError *NotFoundError
if errors.As(err, &notFoundError) {
continue
}
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ go 1.13

require (
github.com/Piszmog/cfservices v1.3.6
github.com/Piszmog/httpclient v1.0.4
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
github.com/golang/protobuf v1.3.2 // indirect
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
google.golang.org/appengine v1.6.5 // indirect
)
10 changes: 4 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Piszmog/cfservices v1.3.6 h1:hFt4MQwRVXzMXKcuMiGbUb56j+ns4wwsCVckSy1POAU=
github.com/Piszmog/cfservices v1.3.6/go.mod h1:kqqfwtk5qUXqg/axf+8eECqFE3n06S/+9qWNPasF0v4=
github.com/Piszmog/httpclient v1.0.4 h1:FoI7KdLP1wJc4SwvwHk4xb7bt2d75gmeqablhMeSIVs=
github.com/Piszmog/httpclient v1.0.4/go.mod h1:w1G59xd8Dks8cucZVXuMv0MCl3n7Z/9Lq1Xm5YBFlaE=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand All @@ -12,10 +10,10 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA=
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
12 changes: 12 additions & 0 deletions io.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package cloudconfigclient

import (
"fmt"
"io"
)

func closeResource(r io.Closer) {
if err := r.Close(); err != nil {
fmt.Println(fmt.Errorf("failed to close resource: %w", err))
}
}
13 changes: 5 additions & 8 deletions local.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package cloudconfigclient
import (
"fmt"
"github.com/Piszmog/cfservices"
"github.com/Piszmog/httpclient"
"net/http"
"os"
"strings"
)
Expand All @@ -17,7 +17,7 @@ const (
// environment variable 'CONFIG_SERVER_URLS'.
//
// The ConfigClient's underlying http.Client is configured with timeouts and connection pools.
func CreateLocalClientFromEnv() (*ConfigClient, error) {
func CreateLocalClientFromEnv(client *http.Client) (*ConfigClient, error) {
serviceCredentials, err := GetLocalCredentials()
if err != nil {
return nil, fmt.Errorf("failed to create a local client: %w", err)
Expand All @@ -26,17 +26,16 @@ func CreateLocalClientFromEnv() (*ConfigClient, error) {
for index, cred := range serviceCredentials.Credentials {
baseUrls[index] = cred.Uri
}
return CreateLocalClient(baseUrls)
return CreateLocalClient(client, baseUrls)
}

// CreateLocalClient creates a ConfigClient for a locally running Config Server.
//
// The ConfigClient's underlying http.Client is configured with timeouts and connection pools.
func CreateLocalClient(baseUrls []string) (*ConfigClient, error) {
func CreateLocalClient(client *http.Client, baseUrls []string) (*ConfigClient, error) {
configClients := make([]CloudClient, len(baseUrls), len(baseUrls))
for index, baseUrl := range baseUrls {
configUri := baseUrl
client := httpclient.CreateDefaultHttpClient()
configClients[index] = Client{configUri: configUri, httpClient: client}
}
return &ConfigClient{Clients: configClients}, nil
Expand All @@ -53,9 +52,7 @@ func GetLocalCredentials() (*cfservices.ServiceCredentials, error) {
urls := strings.Split(localUrls, ",")
creds := make([]cfservices.Credentials, len(urls), len(urls))
for index, url := range urls {
creds[index] = cfservices.Credentials{
Uri: url,
}
creds[index] = cfservices.Credentials{Uri: url}
}
return &cfservices.ServiceCredentials{Credentials: creds}, nil
}
26 changes: 20 additions & 6 deletions local_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
package cloudconfigclient

import (
"fmt"
"net/http"
"os"
"testing"
)

func TestCreateLocalClient(t *testing.T) {
const localURI = "http://localhost:8080"
os.Setenv(EnvironmentLocalConfigServerUrls, localURI)
defer os.Unsetenv(EnvironmentLocalConfigServerUrls)
configClient, err := CreateLocalClientFromEnv()
if err := os.Setenv(EnvironmentLocalConfigServerUrls, localURI); err != nil {
t.Fatal(err)
}
defer func() {
if err := os.Unsetenv(EnvironmentLocalConfigServerUrls); err != nil {
fmt.Println(err)
}
}()
configClient, err := CreateLocalClientFromEnv(&http.Client{})
if err != nil {
t.Errorf("failed to create local client with error %v", err)
}
Expand All @@ -19,7 +27,7 @@ func TestCreateLocalClient(t *testing.T) {
}

func TestCreateLocalClientWhenENVNotSet(t *testing.T) {
configClient, err := CreateLocalClientFromEnv()
configClient, err := CreateLocalClientFromEnv(&http.Client{})
if err == nil {
t.Errorf("failed to create local client with error %v", err)
}
Expand All @@ -30,8 +38,14 @@ func TestCreateLocalClientWhenENVNotSet(t *testing.T) {

func TestGetLocalCredentials(t *testing.T) {
const localURI = "http://localhost:8080"
os.Setenv(EnvironmentLocalConfigServerUrls, localURI)
defer os.Unsetenv(EnvironmentLocalConfigServerUrls)
if err := os.Setenv(EnvironmentLocalConfigServerUrls, localURI); err != nil {
t.Fatal(err)
}
defer func() {
if err := os.Unsetenv(EnvironmentLocalConfigServerUrls); err != nil {
fmt.Println(err)
}
}()
serviceCredentials, err := GetLocalCredentials()
if err != nil {
t.Errorf("failed to get local credentials with error %v", err)
Expand Down
16 changes: 16 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Parameters
GO_CMD=go
GO_BUILD=$(GO_CMD) build
GO_CLEAN=$(GO_CMD) clean
GO_TEST=$(GO_CMD) test

# Commands
all: clean vet test build
clean:
$(GO_CLEAN)
vet:
$(GO_CMD) vet
test:
$(GO_TEST) -v ./...
build:
$(GO_BUILD)
5 changes: 2 additions & 3 deletions net/oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package net

import (
"errors"
"fmt"
"github.com/Piszmog/cfservices"
"golang.org/x/net/context"
"golang.org/x/oauth2/clientcredentials"
Expand All @@ -13,15 +12,15 @@ import (
func CreateOAuth2Client(cred *cfservices.Credentials) (*http.Client, error) {
config, err := CreateOAuth2Config(cred)
if err != nil {
return nil, fmt.Errorf("failed to create oauth2 config: %w", err)
return nil, err
}
return config.Client(context.Background()), nil
}

// CreateOAuth2Config creates an OAuth2 config from the provided credentials.
func CreateOAuth2Config(cred *cfservices.Credentials) (*clientcredentials.Config, error) {
if cred == nil {
return nil, errors.New("cannot create oauth2 config when credentials are nil")
return nil, errors.New("no credentials provided")
}
return &clientcredentials.Config{
ClientID: cred.ClientId,
Expand Down
3 changes: 2 additions & 1 deletion resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
const (
defaultApplicationName = "default"
defaultApplicationProfile = "default"
useDefaultLabel = "useDefaultLabel=true"
)

// Resource interface describes how to retrieve files from the Config Server.
Expand All @@ -22,7 +23,7 @@ type Resource interface {
func (c ConfigClient) GetFile(directory string, file string, interfaceType interface{}) error {
fileFound := false
for _, client := range c.Clients {
if err := getResource(client, interfaceType, defaultApplicationName, defaultApplicationProfile, directory, file+"?useDefaultLabel=true"); err != nil {
if err := getResource(client, interfaceType, defaultApplicationName, defaultApplicationProfile, directory, file+"?"+useDefaultLabel); err != nil {
var notFoundError *NotFoundError
if errors.As(err, &notFoundError) {
continue
Expand Down

0 comments on commit 0666a8b

Please sign in to comment.