예제 #1
0
func execTask(t *task) {
	defer func() {
		t.CompleteTime = time.Now().Unix()
		if t.Error != nil {
			t.ctx.Error(t.Error)
			t.State = types.TaskStateError
		} else {
			t.State = types.TaskStateSuccess
		}
		close(t.done)
		t.ctx.Debug("task completed")
	}()

	t.State = types.TaskStateRunning
	t.StartTime = time.Now().Unix()

	t.ctx.Info("executing task")

	if t.storRunFunc != nil && t.storService != nil {
		t.Result, t.Error = t.storRunFunc(t.ctx, t.storService)
	} else if t.runFunc != nil {
		t.Result, t.Error = t.runFunc(t.ctx)
	} else {
		t.Error = goof.New("invalid task")
	}

	if t.Error != nil {
		return
	}

	if t.Result == nil {
		t.ctx.Debug("skipping response schema validation; result == nil")
		return
	}

	if t.resultSchema == nil {
		t.ctx.Debug("skipping response schema validation; schema == nil")
		return
	}

	if !t.resultSchemaValidationEnabled {
		t.ctx.Debug("skipping response schema validation; disabled")
		return
	}

	var buf []byte
	if buf, t.Error = json.Marshal(t.Result); t.Error != nil {
		return
	}

	t.Error = schema.Validate(t.ctx, t.resultSchema, buf)
	if t.Error != nil {
		return
	}
}
// Handle is the type's Handler function.
func (h *schemaValidator) Handle(
	ctx types.Context,
	w http.ResponseWriter,
	req *http.Request,
	store types.Store) error {

	reqBody, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return fmt.Errorf("validate req schema: read req error: %v", err)
	}

	// do the request validation
	if h.reqSchema != nil {
		err = schema.Validate(ctx, h.reqSchema, reqBody)
		if err != nil {
			return fmt.Errorf("validate req schema: validation error: %v", err)
		}
	}

	// create the object for the request payload if there is a function for it
	if h.newReqObjFunc != nil {
		reqObj := h.newReqObjFunc()
		if len(reqBody) > 0 {
			if err = json.Unmarshal(reqBody, reqObj); err != nil {
				return fmt.Errorf(
					"validate req schema: unmarshal error: %v", err)
			}
		}
		ctx = ctx.WithValue("reqObj", reqObj)
	}

	// if there's not response schema then just return the result of the next
	// handler
	if DisableResponseValidation || h.resSchema == nil {
		return h.handler(ctx, w, req, store)
	}

	// at this point we know there's going to be response validation, so
	// we need to record the result of the next handler in order to intercept
	// the response payload to validate it
	rec := httptest.NewRecorder()

	// invoke the next handler with a recorder
	err = h.handler(ctx, rec, req, store)
	if err != nil {
		return err
	}

	// do the response validation
	resBody := rec.Body.Bytes()
	err = schema.Validate(ctx, h.resSchema, resBody)
	if err != nil {
		return err
	}

	// write the recorded result of the next handler to the resposne writer
	w.WriteHeader(rec.Code)
	for k, v := range rec.HeaderMap {
		w.Header()[k] = v
	}
	if _, err = w.Write(resBody); err != nil {
		return err
	}

	return nil
}