예제 #1
0
// LoadResource returns an object from the database that matches the specified
// resource type and object identifier.
func (rc *ResourceController) LoadResource(resourceType string, id bson.ObjectId) (interface{}, error) {
	// Determine the collection expected to hold the resource
	c := rc.Database().C(ptm_models.GetCollectionName(resourceType))
	result := ptm_models.NewStructForResourceName(resourceType)
	err := c.Find(bson.M{"_id": id}).One(result)
	if err != nil {
		return nil, err
	}
	logger.Log.WithFields(logrus.Fields{"result": result}).Debug("LoadResource")
	return result, nil
}
예제 #2
0
// CreateResource creates an instance of the resource associated with
// the request url, writes the body of the request into the new object,
// and then persists the object in the database. A unique identifier is
// created and associated with the object. A copy of the object that was
// stored in the database is returned in the response.
func (rc *ResourceController) CreateResource(ctx *gin.Context) {
	req := ctx.Request
	resourceType := getResourceType(req.URL)
	resource := ptm_models.NewStructForResourceName(resourceType)
	if err := ctx.Bind(resource); err != nil {
		ctx.AbortWithError(http.StatusBadRequest, err)
		return
	}

	res, err := ptm_models.PersistResource(rc.Database(), resourceType, resource)
	if err != nil {
		ctx.AbortWithError(http.StatusInternalServerError, err)
		return
	}

	id := reflect.ValueOf(res).Elem().FieldByName("ID").String()

	logger.Log.WithFields(
		logrus.Fields{"res type": resourceType, "id": id}).Info("CreateResource")

	ctx.Header("Location", responseURL(req, resourceType, id).String())

	ctx.JSON(http.StatusCreated, res)
}
예제 #3
0
func (rc *ResourceController) UpdateResource(ctx *gin.Context) {
	var id bson.ObjectId

	// Section 9.6 of RFC 2616 says to return 201 if resource didn't already exist
	// and 200 or 204, otherwise
	// http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
	var statusCode int = http.StatusOK

	req := ctx.Request
	resourceType := getResourceType(req.URL)

	// Validate id as a bson Object ID
	id, err := toBsonObjectID(ctx.Param("id"))
	if err != nil {
		ctx.AbortWithError(http.StatusBadRequest, err)
		return
	}

	var createdOn reflect.Value

	// Determine if the resource already exists
	existing, err := rc.LoadResource(resourceType, id)
	if err != nil {
		if err == mgo.ErrNotFound {
			statusCode = http.StatusCreated
		} else {
			ctx.AbortWithError(http.StatusInternalServerError, err)
			return
		}
	} else {
		//		reflect.ValueOf(&n).Elem().FieldByName("N").Set(reflect.ValueOf(ft))
		metaField := reflect.ValueOf(existing).Elem().FieldByName("Meta")
		createdOn = metaField.Elem().FieldByName("CreatedOn")
		logger.Log.WithFields(
			logrus.Fields{"createdOn": createdOn}).Info("UpdateResource")
	}

	resource := ptm_models.NewStructForResourceName(resourceType)
	if err := ctx.Bind(resource); err != nil {
		ctx.AbortWithError(http.StatusInternalServerError, err)
		return
	}

	c := rc.Database().C(ptm_models.GetCollectionName(resourceType))
	// Force the ID provided in the URL to be in the resource object
	reflect.ValueOf(resource).Elem().FieldByName("ID").Set(reflect.ValueOf(id))
	ptm_models.UpdateLastUpdatedDate(resource)
	// Ensure the creation date does not change`
	metaField := reflect.ValueOf(resource).Elem().FieldByName("Meta")
	metaField.Elem().FieldByName("CreatedOn").Set(createdOn)
	createdOn2 := metaField.Elem().FieldByName("CreatedOn")
	logger.Log.WithFields(
		logrus.Fields{"createdOn2": createdOn2}).Info("UpdateResource")
	err = c.Update(bson.M{"_id": id}, resource)
	if err != nil {
		ctx.AbortWithError(http.StatusInternalServerError, err)
		return
	}

	logger.Log.WithFields(
		logrus.Fields{"collection": ptm_models.GetCollectionName(resourceType),
			"res type": resourceType, "id": id, "createdOn": createdOn}).Info("UpdateResource")

	ctx.Header("Location", responseURL(req, resourceType, id.Hex()).String())

	ctx.JSON(statusCode, resource)
}