This repository has been archived by the owner on May 6, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #124 from chmouel/witng
Check that space exists
- Loading branch information
Showing
14 changed files
with
370 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,3 +81,4 @@ tool/ | |
migration/sqlbindata.go | ||
environment/generated/ | ||
auth/client | ||
application/wit/witservice |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package rest | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
|
||
"github.com/goadesign/goa/client" | ||
) | ||
|
||
// Doer is a wrapper interface for goa client Doer | ||
type HttpDoer interface { | ||
client.Doer | ||
} | ||
|
||
// HttpClient defines the Do method of the http client. | ||
type HttpClient interface { | ||
Do(req *http.Request) (*http.Response, error) | ||
} | ||
|
||
// HttpClientDoer implements HttpDoer | ||
type HttpClientDoer struct { | ||
HttpClient HttpClient | ||
} | ||
|
||
// DefaultHttpDoer creates a new HttpDoer with default http client | ||
func DefaultHttpDoer() HttpDoer { | ||
return &HttpClientDoer{HttpClient: http.DefaultClient} | ||
} | ||
|
||
// Do overrides Do method of the default goa client Doer. It's needed for mocking http clients in tests. | ||
func (d *HttpClientDoer) Do(ctx context.Context, req *http.Request) (*http.Response, error) { | ||
return d.HttpClient.Do(req) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package rest | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"net/http" | ||
"net/url" | ||
) | ||
|
||
// AbsoluteURL prefixes a relative URL with absolute address | ||
func AbsoluteURL(req *http.Request, relative string) string { | ||
scheme := "http" | ||
if req.URL != nil && req.URL.Scheme == "https" { // isHTTPS | ||
scheme = "https" | ||
} | ||
xForwardProto := req.Header.Get("X-Forwarded-Proto") | ||
if xForwardProto != "" { | ||
scheme = xForwardProto | ||
} | ||
return fmt.Sprintf("%s://%s%s", scheme, req.Host, relative) | ||
} | ||
|
||
// AbsoluteURLAsURL returns the result of AbsoluteURL parsed into a URL | ||
// structure and a potential parsing error. | ||
func AbsoluteURLAsURL(req *http.Request, relative string) (*url.URL, error) { | ||
return url.Parse(AbsoluteURL(req, relative)) | ||
} | ||
|
||
// ReadBody reads body from a ReadCloser and returns it as a string | ||
func ReadBody(body io.ReadCloser) string { | ||
buf := new(bytes.Buffer) | ||
_, _ = buf.ReadFrom(body) | ||
return buf.String() | ||
} | ||
|
||
// CloseResponse reads the body and close the response. To be used to prevent file descriptor leaks. | ||
func CloseResponse(response *http.Response) { | ||
_, _ = ioutil.ReadAll(response.Body) | ||
response.Body.Close() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package application | ||
|
||
import ( | ||
"github.com/fabric8-services/fabric8-build/application/wit" | ||
"github.com/fabric8-services/fabric8-build/configuration" | ||
) | ||
|
||
type ServiceFactory interface { | ||
WITService() wit.WITService | ||
} | ||
|
||
type serviceFactoryImpl struct { | ||
Config *configuration.Config | ||
} | ||
|
||
func (s serviceFactoryImpl) WITService() wit.WITService { | ||
return &wit.WITServiceImpl{ | ||
Config: *s.Config, | ||
} | ||
} | ||
|
||
func NewServiceFactory(config *configuration.Config) ServiceFactory { | ||
return serviceFactoryImpl{ | ||
Config: config, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package wit | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
"net/url" | ||
|
||
"github.com/fabric8-services/fabric8-build/application/rest" | ||
"github.com/fabric8-services/fabric8-build/application/wit/witservice" | ||
"github.com/fabric8-services/fabric8-build/configuration" | ||
commonerr "github.com/fabric8-services/fabric8-common/errors" | ||
"github.com/fabric8-services/fabric8-common/goasupport" | ||
"github.com/pkg/errors" | ||
|
||
"github.com/goadesign/goa/uuid" | ||
"github.com/prometheus/common/log" | ||
) | ||
|
||
type Space struct { | ||
ID uuid.UUID | ||
OwnerID uuid.UUID | ||
Name string | ||
Description string | ||
} | ||
|
||
type WITService interface { | ||
GetSpace(ctx context.Context, spaceID string) (space *Space, e error) | ||
} | ||
|
||
type WITServiceImpl struct { | ||
Config configuration.Config | ||
doer rest.HttpDoer | ||
} | ||
|
||
// GetSpace talks to the WIT service to retrieve a space record for the specified spaceID, then returns space | ||
func (s *WITServiceImpl) GetSpace(ctx context.Context, spaceID string) (space *Space, e error) { | ||
remoteWITService, err := s.createClientWithContextSigner(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
spaceIDUUID, err := uuid.FromString(spaceID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res, err := remoteWITService.ShowSpace(ctx, witservice.ShowSpacePath(spaceIDUUID), nil, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
defer rest.CloseResponse(res) | ||
if res.StatusCode != http.StatusOK { | ||
bodyString := rest.ReadBody(res.Body) | ||
log.Error(ctx, map[string]interface{}{ | ||
"spaceId": spaceID, | ||
"response_status": res.Status, | ||
"response_body": bodyString, | ||
}, "unable to get space from WIT") | ||
if res.StatusCode == 404 { | ||
return nil, commonerr.NewNotFoundErrorFromString("Cannot find space: " + spaceID) | ||
} else { | ||
return nil, errors.Errorf("unable to get space from WIT. Response status: %s. Response body: %s", res.Status, bodyString) | ||
} | ||
} | ||
|
||
spaceSingle, err := remoteWITService.DecodeSpaceSingle(res) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &Space{ | ||
ID: *spaceSingle.Data.ID, | ||
Name: *spaceSingle.Data.Attributes.Name, | ||
Description: *spaceSingle.Data.Attributes.Description, | ||
OwnerID: *spaceSingle.Data.Relationships.OwnedBy.Data.ID}, nil | ||
} | ||
|
||
// createClientWithContextSigner creates with a signer based on current context | ||
func (s *WITServiceImpl) createClientWithContextSigner(ctx context.Context) (*witservice.Client, error) { | ||
c, err := s.createClient() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
c.SetJWTSigner(goasupport.NewForwardSigner(ctx)) | ||
return c, nil | ||
} | ||
|
||
func (s *WITServiceImpl) createClient() (*witservice.Client, error) { | ||
witURL, e := s.Config.GetWITURL() | ||
if e != nil { | ||
return nil, e | ||
} | ||
u, err := url.Parse(witURL) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
c := witservice.New(s.doer) | ||
c.Host = u.Host | ||
c.Scheme = u.Scheme | ||
return c, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.