forked from LaconicNetwork/kompose
Upgrade OpenShift and its dependencies.
OpenShift version 1.4.0-alpha.0
This commit is contained in:
+4
-4
@@ -40,7 +40,7 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo
|
||||
|
||||
- Routes for request → function mapping with path parameter (e.g. {id}) support
|
||||
- Configurable router:
|
||||
- Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but doest **not** accept) regular expressions (See RouterJSR311 which is used by default)
|
||||
- Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions (See RouterJSR311 which is used by default)
|
||||
- Fast routing algorithm that allows static elements, regular expressions and dynamic parameters in the URL path (e.g. /meetings/{id} or /static/{subpath:*}, See CurlyRouter)
|
||||
- Request API for reading structs from JSON/XML and accesing parameters (path,query,header)
|
||||
- Response API for writing structs to JSON/XML and setting headers
|
||||
@@ -61,8 +61,8 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo
|
||||
|
||||
- [Documentation on godoc.org](http://godoc.org/github.com/emicklei/go-restful)
|
||||
- [Code examples](https://github.com/emicklei/go-restful/tree/master/examples)
|
||||
- [Example posted on blog](http://ernestmicklei.com/2012/11/24/go-restful-first-working-example/)
|
||||
- [Design explained on blog](http://ernestmicklei.com/2012/11/11/go-restful-api-design/)
|
||||
- [Example posted on blog](http://ernestmicklei.com/2012/11/go-restful-first-working-example/)
|
||||
- [Design explained on blog](http://ernestmicklei.com/2012/11/go-restful-api-design/)
|
||||
- [sourcegraph](https://sourcegraph.com/github.com/emicklei/go-restful)
|
||||
- [gopkg.in](https://gopkg.in/emicklei/go-restful.v1)
|
||||
- [showcase: Mora - MongoDB REST Api server](https://github.com/emicklei/mora)
|
||||
@@ -71,4 +71,4 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo
|
||||
|
||||
(c) 2012 - 2015, http://ernestmicklei.com. MIT License
|
||||
|
||||
Type ```git shortlog -s``` for a full list of contributors.
|
||||
Type ```git shortlog -s``` for a full list of contributors.
|
||||
|
||||
+4
-4
@@ -283,12 +283,12 @@ func fixedPrefixPath(pathspec string) string {
|
||||
}
|
||||
|
||||
// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server
|
||||
func (c Container) ServeHTTP(httpwriter http.ResponseWriter, httpRequest *http.Request) {
|
||||
func (c *Container) ServeHTTP(httpwriter http.ResponseWriter, httpRequest *http.Request) {
|
||||
c.ServeMux.ServeHTTP(httpwriter, httpRequest)
|
||||
}
|
||||
|
||||
// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics.
|
||||
func (c Container) Handle(pattern string, handler http.Handler) {
|
||||
func (c *Container) Handle(pattern string, handler http.Handler) {
|
||||
c.ServeMux.Handle(pattern, handler)
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ func (c *Container) Filter(filter FilterFunction) {
|
||||
}
|
||||
|
||||
// RegisteredWebServices returns the collections of added WebServices
|
||||
func (c Container) RegisteredWebServices() []*WebService {
|
||||
func (c *Container) RegisteredWebServices() []*WebService {
|
||||
c.webServicesLock.RLock()
|
||||
defer c.webServicesLock.RUnlock()
|
||||
result := make([]*WebService, len(c.webServices))
|
||||
@@ -329,7 +329,7 @@ func (c Container) RegisteredWebServices() []*WebService {
|
||||
}
|
||||
|
||||
// computeAllowedMethods returns a list of HTTP methods that are valid for a Request
|
||||
func (c Container) computeAllowedMethods(req *Request) []string {
|
||||
func (c *Container) computeAllowedMethods(req *Request) []string {
|
||||
// Go through all RegisteredWebServices() and all its Routes to collect the options
|
||||
methods := []string{}
|
||||
requestPath := req.Request.URL.Path
|
||||
|
||||
+6
-6
@@ -44,16 +44,16 @@ func (c CurlyRouter) SelectRoute(
|
||||
}
|
||||
|
||||
// selectRoutes return a collection of Route from a WebService that matches the path tokens from the request.
|
||||
func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) []Route {
|
||||
candidates := &sortableCurlyRoutes{[]*curlyRoute{}}
|
||||
func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes {
|
||||
candidates := sortableCurlyRoutes{}
|
||||
for _, each := range ws.routes {
|
||||
matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens)
|
||||
if matches {
|
||||
candidates.add(&curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers?
|
||||
candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers?
|
||||
}
|
||||
}
|
||||
sort.Sort(sort.Reverse(candidates))
|
||||
return candidates.routes()
|
||||
return candidates
|
||||
}
|
||||
|
||||
// matchesRouteByPathTokens computes whether it matches, howmany parameters do match and what the number of static path elements are.
|
||||
@@ -110,9 +110,9 @@ func (c CurlyRouter) regularMatchesPathToken(routeToken string, colon int, reque
|
||||
|
||||
// detectRoute selectes from a list of Route the first match by inspecting both the Accept and Content-Type
|
||||
// headers of the Request. See also RouterJSR311 in jsr311.go
|
||||
func (c CurlyRouter) detectRoute(candidateRoutes []Route, httpRequest *http.Request) (*Route, error) {
|
||||
func (c CurlyRouter) detectRoute(candidateRoutes sortableCurlyRoutes, httpRequest *http.Request) (*Route, error) {
|
||||
// tracing is done inside detectRoute
|
||||
return RouterJSR311{}.detectRoute(candidateRoutes, httpRequest)
|
||||
return RouterJSR311{}.detectRoute(candidateRoutes.routes(), httpRequest)
|
||||
}
|
||||
|
||||
// detectWebService returns the best matching webService given the list of path tokens.
|
||||
|
||||
+13
-15
@@ -11,30 +11,28 @@ type curlyRoute struct {
|
||||
staticCount int
|
||||
}
|
||||
|
||||
type sortableCurlyRoutes struct {
|
||||
candidates []*curlyRoute
|
||||
type sortableCurlyRoutes []curlyRoute
|
||||
|
||||
func (s *sortableCurlyRoutes) add(route curlyRoute) {
|
||||
*s = append(*s, route)
|
||||
}
|
||||
|
||||
func (s *sortableCurlyRoutes) add(route *curlyRoute) {
|
||||
s.candidates = append(s.candidates, route)
|
||||
}
|
||||
|
||||
func (s *sortableCurlyRoutes) routes() (routes []Route) {
|
||||
for _, each := range s.candidates {
|
||||
func (s sortableCurlyRoutes) routes() (routes []Route) {
|
||||
for _, each := range s {
|
||||
routes = append(routes, each.route) // TODO change return type
|
||||
}
|
||||
return routes
|
||||
}
|
||||
|
||||
func (s *sortableCurlyRoutes) Len() int {
|
||||
return len(s.candidates)
|
||||
func (s sortableCurlyRoutes) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
func (s *sortableCurlyRoutes) Swap(i, j int) {
|
||||
s.candidates[i], s.candidates[j] = s.candidates[j], s.candidates[i]
|
||||
func (s sortableCurlyRoutes) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
func (s *sortableCurlyRoutes) Less(i, j int) bool {
|
||||
ci := s.candidates[i]
|
||||
cj := s.candidates[j]
|
||||
func (s sortableCurlyRoutes) Less(i, j int) bool {
|
||||
ci := s[i]
|
||||
cj := s[j]
|
||||
|
||||
// primary key
|
||||
if ci.staticCount < cj.staticCount {
|
||||
|
||||
+7
-6
@@ -1,9 +1,10 @@
|
||||
cd examples
|
||||
ls *.go | xargs -I {} go build -o /tmp/ignore {}
|
||||
cd ..
|
||||
go fmt ...swagger && \
|
||||
go test -test.v ...restful && \
|
||||
go test -test.v ...swagger && \
|
||||
go vet ...restful && \
|
||||
go fmt ...swagger && \
|
||||
go install ...swagger && \
|
||||
go fmt ...restful && \
|
||||
go test -test.v ...restful && \
|
||||
go install ...restful
|
||||
go install ...restful
|
||||
cd examples
|
||||
ls *.go | xargs -I {} go build -o /tmp/ignore {}
|
||||
cd ..
|
||||
+3
-2
@@ -74,7 +74,7 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R
|
||||
// accept
|
||||
outputMediaOk := []Route{}
|
||||
accept := httpRequest.Header.Get(HEADER_Accept)
|
||||
if accept == "" {
|
||||
if len(accept) == 0 {
|
||||
accept = "*/*"
|
||||
}
|
||||
for _, each := range inputMediaOk {
|
||||
@@ -88,7 +88,8 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R
|
||||
}
|
||||
return nil, NewError(http.StatusNotAcceptable, "406: Not Acceptable")
|
||||
}
|
||||
return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil
|
||||
// return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil
|
||||
return &outputMediaOk[0], nil
|
||||
}
|
||||
|
||||
// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2
|
||||
|
||||
+4
-4
@@ -130,25 +130,25 @@ func (r *Response) WriteHeaderAndEntity(status int, value interface{}) error {
|
||||
}
|
||||
|
||||
// WriteAsXml is a convenience method for writing a value in xml (requires Xml tags on the value)
|
||||
// It uses the standard encoding/xml package for marshalling the valuel ; not using a registered EntityReaderWriter.
|
||||
// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter.
|
||||
func (r *Response) WriteAsXml(value interface{}) error {
|
||||
return writeXML(r, http.StatusOK, MIME_XML, value)
|
||||
}
|
||||
|
||||
// WriteHeaderAndXml is a convenience method for writing a status and value in xml (requires Xml tags on the value)
|
||||
// It uses the standard encoding/xml package for marshalling the valuel ; not using a registered EntityReaderWriter.
|
||||
// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter.
|
||||
func (r *Response) WriteHeaderAndXml(status int, value interface{}) error {
|
||||
return writeXML(r, status, MIME_XML, value)
|
||||
}
|
||||
|
||||
// WriteAsJson is a convenience method for writing a value in json.
|
||||
// It uses the standard encoding/json package for marshalling the valuel ; not using a registered EntityReaderWriter.
|
||||
// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter.
|
||||
func (r *Response) WriteAsJson(value interface{}) error {
|
||||
return writeJSON(r, http.StatusOK, MIME_JSON, value)
|
||||
}
|
||||
|
||||
// WriteJson is a convenience method for writing a value in Json with a given Content-Type.
|
||||
// It uses the standard encoding/json package for marshalling the valuel ; not using a registered EntityReaderWriter.
|
||||
// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter.
|
||||
func (r *Response) WriteJson(value interface{}, contentType string) error {
|
||||
return writeJSON(r, http.StatusOK, contentType, value)
|
||||
}
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ func (b *RouteBuilder) Param(parameter *Parameter) *RouteBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
// Operation allows you to document what the acutal method/function call is of the Route.
|
||||
// Operation allows you to document what the actual method/function call is of the Route.
|
||||
// Unless called, the operation name is derived from the RouteFunction set using To(..).
|
||||
func (b *RouteBuilder) Operation(name string) *RouteBuilder {
|
||||
b.operation = name
|
||||
|
||||
+4
@@ -9,6 +9,8 @@ import (
|
||||
// PostBuildDeclarationMapFunc can be used to modify the api declaration map.
|
||||
type PostBuildDeclarationMapFunc func(apiDeclarationMap *ApiDeclarationList)
|
||||
|
||||
type MapSchemaFormatFunc func(typeName string) string
|
||||
|
||||
type Config struct {
|
||||
// url where the services are available, e.g. http://localhost:8080
|
||||
// if left empty then the basePath of Swagger is taken from the actual request
|
||||
@@ -31,4 +33,6 @@ type Config struct {
|
||||
PostBuildHandler PostBuildDeclarationMapFunc
|
||||
// Swagger global info struct
|
||||
Info Info
|
||||
// [optional] If set, model builder should call this handler to get addition typename-to-swagger-format-field convertion.
|
||||
SchemaFormatHandler MapSchemaFormatFunc
|
||||
}
|
||||
|
||||
+20
-1
@@ -14,6 +14,7 @@ type ModelBuildable interface {
|
||||
|
||||
type modelBuilder struct {
|
||||
Models *ModelList
|
||||
Config *Config
|
||||
}
|
||||
|
||||
type documentable interface {
|
||||
@@ -50,6 +51,14 @@ func (b modelBuilder) addModel(st reflect.Type, nameOverride string) *Model {
|
||||
if b.isPrimitiveType(modelName) {
|
||||
return nil
|
||||
}
|
||||
// golang encoding/json packages says array and slice values encode as
|
||||
// JSON arrays, except that []byte encodes as a base64-encoded string.
|
||||
// If we see a []byte here, treat it at as a primitive type (string)
|
||||
// and deal with it in buildArrayTypeProperty.
|
||||
if (st.Kind() == reflect.Slice || st.Kind() == reflect.Array) &&
|
||||
st.Elem().Kind() == reflect.Uint8 {
|
||||
return nil
|
||||
}
|
||||
// see if we already have visited this model
|
||||
if _, ok := b.Models.At(modelName); ok {
|
||||
return nil
|
||||
@@ -231,7 +240,7 @@ func (b modelBuilder) buildStructTypeProperty(field reflect.StructField, jsonNam
|
||||
|
||||
if field.Name == fieldType.Name() && field.Anonymous && !hasNamedJSONTag(field) {
|
||||
// embedded struct
|
||||
sub := modelBuilder{new(ModelList)}
|
||||
sub := modelBuilder{new(ModelList), b.Config}
|
||||
sub.addModel(fieldType, "")
|
||||
subKey := sub.keyFrom(fieldType)
|
||||
// merge properties from sub
|
||||
@@ -275,6 +284,11 @@ func (b modelBuilder) buildArrayTypeProperty(field reflect.StructField, jsonName
|
||||
return jsonName, prop
|
||||
}
|
||||
fieldType := field.Type
|
||||
if fieldType.Elem().Kind() == reflect.Uint8 {
|
||||
stringt := "string"
|
||||
prop.Type = &stringt
|
||||
return jsonName, prop
|
||||
}
|
||||
var pType = "array"
|
||||
prop.Type = &pType
|
||||
isPrimitive := b.isPrimitiveType(fieldType.Elem().Name())
|
||||
@@ -410,6 +424,11 @@ func (b modelBuilder) jsonSchemaType(modelName string) string {
|
||||
}
|
||||
|
||||
func (b modelBuilder) jsonSchemaFormat(modelName string) string {
|
||||
if b.Config != nil && b.Config.SchemaFormatHandler != nil {
|
||||
if mapped := b.Config.SchemaFormatHandler(modelName); mapped != "" {
|
||||
return mapped
|
||||
}
|
||||
}
|
||||
schemaMap := map[string]string{
|
||||
"int": "int32",
|
||||
"int32": "int32",
|
||||
|
||||
+1
@@ -118,6 +118,7 @@ type ApiDeclaration struct {
|
||||
ApiVersion string `json:"apiVersion"`
|
||||
BasePath string `json:"basePath"`
|
||||
ResourcePath string `json:"resourcePath"` // must start with /
|
||||
Info Info `json:"info"`
|
||||
Apis []Api `json:"apis,omitempty"`
|
||||
Models ModelList `json:"models,omitempty"`
|
||||
Produces []string `json:"produces,omitempty"`
|
||||
|
||||
+7
-7
@@ -241,7 +241,7 @@ func (sws SwaggerService) composeDeclaration(ws *restful.WebService, pathPrefix
|
||||
DataTypeFields: DataTypeFields{Type: &voidString},
|
||||
Parameters: []Parameter{},
|
||||
Nickname: route.Operation,
|
||||
ResponseMessages: composeResponseMessages(route, &decl)}
|
||||
ResponseMessages: composeResponseMessages(route, &decl, &sws.config)}
|
||||
|
||||
operation.Consumes = route.Consumes
|
||||
operation.Produces = route.Produces
|
||||
@@ -271,7 +271,7 @@ func withoutWildcard(path string) string {
|
||||
}
|
||||
|
||||
// composeResponseMessages takes the ResponseErrors (if any) and creates ResponseMessages from them.
|
||||
func composeResponseMessages(route restful.Route, decl *ApiDeclaration) (messages []ResponseMessage) {
|
||||
func composeResponseMessages(route restful.Route, decl *ApiDeclaration, config *Config) (messages []ResponseMessage) {
|
||||
if route.ResponseErrors == nil {
|
||||
return messages
|
||||
}
|
||||
@@ -294,7 +294,7 @@ func composeResponseMessages(route restful.Route, decl *ApiDeclaration) (message
|
||||
if isCollection {
|
||||
modelName = "array[" + modelName + "]"
|
||||
}
|
||||
modelBuilder{&decl.Models}.addModel(st, "")
|
||||
modelBuilder{Models: &decl.Models, Config: config}.addModel(st, "")
|
||||
// reference the model
|
||||
message.ResponseModel = modelName
|
||||
}
|
||||
@@ -332,11 +332,11 @@ func detectCollectionType(st reflect.Type) (bool, reflect.Type) {
|
||||
// addModelFromSample creates and adds (or overwrites) a Model from a sample resource
|
||||
func (sws SwaggerService) addModelFromSampleTo(operation *Operation, isResponse bool, sample interface{}, models *ModelList) {
|
||||
if isResponse {
|
||||
type_, items := asDataType(sample)
|
||||
type_, items := asDataType(sample, &sws.config)
|
||||
operation.Type = type_
|
||||
operation.Items = items
|
||||
}
|
||||
modelBuilder{models}.addModelFrom(sample)
|
||||
modelBuilder{Models: models, Config: &sws.config}.addModelFrom(sample)
|
||||
}
|
||||
|
||||
func asSwaggerParameter(param restful.ParameterData) Parameter {
|
||||
@@ -411,7 +411,7 @@ func asParamType(kind int) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func asDataType(any interface{}) (*string, *Item) {
|
||||
func asDataType(any interface{}, config *Config) (*string, *Item) {
|
||||
// If it's not a collection, return the suggested model name
|
||||
st := reflect.TypeOf(any)
|
||||
isCollection, st := detectCollectionType(st)
|
||||
@@ -424,7 +424,7 @@ func asDataType(any interface{}) (*string, *Item) {
|
||||
// XXX: This is not very elegant
|
||||
// We create an Item object referring to the given model
|
||||
models := ModelList{}
|
||||
mb := modelBuilder{&models}
|
||||
mb := modelBuilder{Models: &models, Config: config}
|
||||
mb.addModelFrom(any)
|
||||
|
||||
elemTypeName := mb.getElementTypeName(modelName, "", st)
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
@@ -51,7 +51,7 @@ func (w *WebService) ApiVersion(apiVersion string) *WebService {
|
||||
}
|
||||
|
||||
// Version returns the API version for documentation purposes.
|
||||
func (w WebService) Version() string { return w.apiVersion }
|
||||
func (w *WebService) Version() string { return w.apiVersion }
|
||||
|
||||
// Path specifies the root URL template path of the WebService.
|
||||
// All Routes will be relative to this path.
|
||||
@@ -155,7 +155,7 @@ func (w *WebService) Route(builder *RouteBuilder) *WebService {
|
||||
// RemoveRoute removes the specified route, looks for something that matches 'path' and 'method'
|
||||
func (w *WebService) RemoveRoute(path, method string) error {
|
||||
if !w.dynamicRoutes {
|
||||
return fmt.Errorf("dynamic routes are not enabled.")
|
||||
return errors.New("dynamic routes are not enabled.")
|
||||
}
|
||||
w.routesLock.Lock()
|
||||
defer w.routesLock.Unlock()
|
||||
@@ -192,7 +192,7 @@ func (w *WebService) Consumes(accepts ...string) *WebService {
|
||||
}
|
||||
|
||||
// Routes returns the Routes associated with this WebService
|
||||
func (w WebService) Routes() []Route {
|
||||
func (w *WebService) Routes() []Route {
|
||||
if !w.dynamicRoutes {
|
||||
return w.routes
|
||||
}
|
||||
@@ -207,12 +207,12 @@ func (w WebService) Routes() []Route {
|
||||
}
|
||||
|
||||
// RootPath returns the RootPath associated with this WebService. Default "/"
|
||||
func (w WebService) RootPath() string {
|
||||
func (w *WebService) RootPath() string {
|
||||
return w.rootPath
|
||||
}
|
||||
|
||||
// PathParameters return the path parameter names for (shared amoung its Routes)
|
||||
func (w WebService) PathParameters() []*Parameter {
|
||||
func (w *WebService) PathParameters() []*Parameter {
|
||||
return w.pathParameters
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ func (w *WebService) Doc(plainText string) *WebService {
|
||||
}
|
||||
|
||||
// Documentation returns it.
|
||||
func (w WebService) Documentation() string {
|
||||
func (w *WebService) Documentation() string {
|
||||
return w.documentation
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user