Beispiel #1
0
func (g *jsonschema) collectPathParameters(pattern string) []map[string]interface{} {
	vars, err := router.ExtractVariables(pattern)
	if err != nil {
		g.gen.Error(err)
		return nil
	}

	params := make([]map[string]interface{}, 0, len(vars))

	for _, v := range vars {
		param := map[string]interface{}{
			"name": strings.Replace(v.Name, ".", "_", -1),
			"in":   "path",
			"type": "string",
			//"format":
		}

		if v.Pattern != "" {
			param["pattern"] = v.Pattern
		}

		if v.MinCount > 0 {
			param["required"] = true
			param["minItems"] = v.MinCount
		}

		if v.MaxCount > 0 {
			param["maxItems"] = v.MaxCount
		}

		params = append(params, param)
	}

	return params
}
Beispiel #2
0
// generateService generates all the code for the named service.
func (g *svchttp) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) {
	apis := filterAPIs(service, service.Method, index)
	if len(apis) == 0 {
		return
	}

	origServName := service.GetName()
	fullServName := file.GetPackage() + "." + origServName
	servName := generator.CamelCase(origServName)
	gatewayVarName := "_" + servName + "_gatewayDesc"

	g.gen.AddInitf("%s.RegisterGatewayDesc(&%s)", g.runtimePkg.Use(), gatewayVarName)

	g.P(`var `, gatewayVarName, ` = `, g.runtimePkg.Use(), `.GatewayDesc{`)
	g.P(`ServiceName: `, strconv.Quote(fullServName), `,`)
	g.P(`HandlerType: ((*`, servName, `Server)(nil)),`)
	g.P(`Routes: []`, g.runtimePkg.Use(), `.RouteDesc{`)
	for _, api := range apis {
		_, method := api.desc, api.method

		httpMethod, pattern, ok := api.GetMethodAndPattern()
		if !ok {
			g.gen.Fail("xyz.featherhead.http requires a method: pattern")
		}

		if idx := strings.IndexRune(pattern, '?'); idx >= 0 {
			pattern = pattern[:idx]
		}

		g.P(`{`)
		g.P(`Method: `, strconv.Quote(httpMethod), `,`)
		g.P(`Pattern: `, strconv.Quote(pattern), `,`)
		g.P(`Handler: `, g.generateServerCallName(servName, method), `,`)
		g.P("},")
	}
	g.P("},")
	g.P("}")
	g.P()

	// Server handler implementations.
	for _, api := range apis {
		info, method := api.desc, api.method

		inputTypeName := method.GetInputType()
		inputType, _ := g.gen.ObjectNamed(inputTypeName).(*generator.Descriptor)

		httpMethod, pattern, ok := api.GetMethodAndPattern()
		queryParams := map[string]string{}
		if !ok {
			g.gen.Fail("xyz.featherhead.http requires a method: pattern")
		}

		if idx := strings.IndexRune(pattern, '?'); idx >= 0 {
			queryString := pattern[idx+1:]
			pattern = pattern[:idx]

			for _, pair := range strings.SplitN(queryString, "&", -1) {
				idx := strings.Index(pair, "={")
				if pair[len(pair)-1] != '}' || idx < 0 {
					g.gen.Fail("invalid query paramter")
				}
				queryParams[pair[:idx]] = pair[idx+2 : len(pair)-1]
			}
		}

		vars, err := router.ExtractVariables(pattern)
		if err != nil {
			g.gen.Error(err)
			return
		}

		var (
			httpResponseWriter = g.httpPkg.Use() + ".ResponseWriter"
			httpRequest        = g.httpPkg.Use() + ".Request"
			contextContext     = g.contextPkg.Use() + ".Context"
		)

		handlerMethod := g.generateServerCallName(servName, method)
		jujuErrors := g.jujuErrorsPkg.Use()
		g.P("func ", handlerMethod, "(srvDesc *", g.grpcPkg.Use(), ".ServiceDesc, srv interface{}, ctx ", contextContext, ", rw ", httpResponseWriter, ", req *", httpRequest, ") error {")
		g.P("if req.Method != ", strconv.Quote(httpMethod), "{")
		g.P(`  return `, jujuErrors, `.MethodNotAllowedf("expected `, httpMethod, ` request")`)
		g.P("}")
		g.P()

		if len(vars) > 0 {
			routerP := g.routerPkg.Use() + ".P"
			g.P(`params := `, routerP, `(ctx)`)
		}

		g.P(`stream, err := `, g.runtimePkg.Use(), `.NewServerStream(ctx, rw, req, `,
			method.GetServerStreaming(), `, `, method.GetClientStreaming(), `, `, int(info.PageSize), `, func(x interface{}) error {`)
		g.P(`input := x.(*`, g.typeName(inputTypeName), `)`)
		g.P(`_ = input`)
		g.P()

		for param, value := range queryParams {
			g.P("// populate ?", param, "=", value)
			g.generateHttpMapping(inputType, value, "req.URL.Query().Get("+strconv.Quote(param)+")")
		}

		for _, v := range vars {
			g.P("// populate {", v.Name, "}")
			g.generateHttpMapping(inputType, v.Name, "params.Get("+strconv.Quote(v.Name)+")")
		}

		g.P(`return nil`)
		g.P(`})`)
		g.P()

		if !api.stream {
			g.P(`desc := &srvDesc.Methods[`, api.index, `]`)
			g.P(`output, err := desc.Handler(srv, stream.Context(), stream.RecvMsg, nil)`)
			g.P(`if err == nil && output == nil {`)
			g.P(`err = `, g.grpcPkg.Use(), `.Errorf(`, g.grpcCodesPkg.Use(), `.Internal, "internal server error")`)
			g.P(`}`)
			g.P(`if err == nil {`)
			g.P(`err = stream.SendMsg(output)`)
			g.P(`}`)
		} else {
			g.P(`desc := &srvDesc.Streams[`, api.index, `]`)
			g.P(`err = desc.Handler(srv, stream)`)
		}
		g.P(`if err != nil {`)
		g.P(`stream.SetError(err)`)
		g.P(`}`)
		g.P()

		g.P(`return stream.CloseSend()`)
		g.P("}")
		g.P()

	}

}