Example #1
0
func Unmarshal(resp http.ResponseWriter, req *http.Request, value interface{}) error {
	defer req.Body.Close()
	contentType := ContentTypeForRequest(req)
	if t, err := encoding.ContentTypeFromString(contentType); err == nil {
		err := encoding.Unmarshal(t, req.Body, value)
		if err != nil {
			DefaultErrorRenderer(resp, req, err.Error(), http.StatusInternalServerError)
			return err
		}
	} else {
		DefaultErrorRenderer(resp, req, ErrBadContentType.Error(), http.StatusBadRequest)
		return err
	}
	return nil
}
Example #2
0
// This test here shows how to implement two stages of configuring an object.
// First a field in the struct gets the source of the config url from the command line flags.
// Second, the config is fetched and unmarshalled to the object.
// Finally, we parse again so that additional flag values are overlaid onto the struct.
func (suite *TestSuiteCommand) TestCommandReparseFlag(c *C) {
	Register("person", func() (Module, ErrorHandling) {
		return new(person), PanicOnError
	})

	// Generate the auth token required by the server.
	token := auth.NewToken(1*time.Hour).Add("secure", 1)
	header := http.Header{}
	token.SetHeader(header, testutil.PrivateKeyFunc)
	ctx := resource.ContextPutHttpHeader(context.Background(), header)

	suite.template = `
name: joe
age: 21
employee: false
not-a-field: hello
`

	p := &person{
		Age:      18,
		Employee: true,
	}

	RunModule("person", p, strings.Split("--config_url=http://localhost:7986/secure --age=35", " "), nil)

	c.Assert(p.ConfigUrl, Equals, "http://localhost:7986/secure")
	c.Assert(p.Employee, Equals, true)

	data, err := resource.Fetch(ctx, p.ConfigUrl)
	c.Assert(err, IsNil)
	c.Log(string(data))
	err = encoding.Unmarshal(encoding.ContentTypeYAML, bytes.NewBuffer(data), p)
	c.Assert(err, IsNil)
	c.Assert(p.Age, Equals, 21)
	c.Assert(p.Name, Equals, "joe")
	c.Assert(p.Employee, Equals, true) // we don't expect the yaml to change the field.

	ReparseFlags(p)
	c.Assert(p.Age, Equals, 35) // This is overwritten by the flag value
	c.Assert(p.Name, Equals, "joe")
	c.Assert(p.Employee, Equals, true)
}
Example #3
0
// Run the configuration specified in conf against the target.  This will run a series
// of template fetching, applying templates, unmarshaling of the final applied template
// onto the given target object.  After unmarshaling is done, the target's fields are
// examined one by one, by tag, and fields that have template as values are then applied.
func Configure(ctx context.Context, conf Conf, target interface{}, optionalFuncs ...template.FuncMap) error {
	conf.lock.Lock()
	defer conf.lock.Unlock()

	initialData := ContextGetInitialData(ctx)
	if initialData != nil {
		gtemplate.ContextPutTemplateData(ctx, initialData)
	}

	contentType := ContextGetConfigDataType(ctx)

	// Generate a list of functions that will escape the template strings
	// Ex.  "secret" : "{{var "zk://host/path/to/secret"}}"
	// This string will be escaped so that the evaluation happens after the unmarshal step by field tag
	funcs := template.FuncMap{}
	for _, fns := range optionalFuncs {
		funcs = gtemplate.MergeFuncMaps(funcs, fns)
	}

	// Note here we generate escaped versions of function to override what's provided.
	// The actual funcs are used in the struct field-by-field step, for those that are marked by tags.
	stubs := gtemplate.MergeFuncMaps(funcs, generateEscapeFuncsFromFieldTag(target))

	conf.model = map[string]interface{}{}
	for _, url := range conf.Urls {

		// Fetch the config data and execute as if it were template
		applied, err := gtemplate.Execute(ctx, url, stubs)

		if conf.OnDoneExecuteLayer != nil {
			conf.OnDoneExecuteLayer(&conf, url, applied, err)
		}

		if err != nil {
			return err
		}

		// Unmarshal to an intermediate representation
		buff := bytes.NewBuffer(applied)
		err = encoding.Unmarshal(contentType, buff, conf.model)

		if conf.OnDoneUnmarshalLayer != nil {
			conf.OnDoneUnmarshalLayer(&conf, url, err)
		}

		if err != nil {
			return err
		}
	}

	if conf.OnDoneFetching != nil {
		conf.OnDoneFetching(&conf)
	}

	// Now marshal the aggregated model to a buffer and then unmarshal it back to the typed struct
	serialized := new(bytes.Buffer)
	err := encoding.Marshal(contentType, serialized, conf.model)
	if err != nil {
		return err
	}
	conf.serialized = serialized.Bytes()
	err = encoding.Unmarshal(contentType, bytes.NewBuffer(conf.serialized), target)

	if conf.OnDoneSerialize != nil {
		conf.OnDoneSerialize(&conf, err)
	}

	if err != nil {
		return err
	}

	if conf.OnDoneUnmarshal != nil {
		conf.OnDoneUnmarshal(&conf, target)
	}

	// Now look for fields with struct tags and apply the actual templates
	return evalStructFieldTemplates(target, funcs)
}