Skip to content
This repository has been archived by the owner on Mar 26, 2020. It is now read-only.

plugins/geo-rep: Geo-replication Session Create #385

Merged
merged 3 commits into from
Oct 13, 2017
Merged

plugins/geo-rep: Geo-replication Session Create #385

merged 3 commits into from
Oct 13, 2017

Conversation

aravindavk
Copy link
Member

@aravindavk aravindavk commented Oct 10, 2017

REST API to create Geo-replication session create

POST /v1/geo-replication/:mastervolid/:slavevolid

Request body,

{
    "mastervol": MASTER_VOL_NAME,
    "slavevol": SLAVE_VOL_NAME,
    "slavehosts": LIST_OF_SLAVE_HOSTS,
    "slaveuser": SLAVE_USER
}

Updates: #271
Signed-off-by: Aravinda VK avishwan@redhat.com

package georeplication

// GeorepCreateRequest represents REST API request to create Geo-rep session
type GeorepCreateRequest struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Are all the fields required for a valid request ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SlaveUser is optional, if not provided defaults to "root"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, you can set it as omitempty

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

omitempty is required for response struct right? In this case if SlaveUser is not passed then it will be empty string.

"github.com/pborman/uuid"
)

const (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a FYI: These can be like enums instead. There's stringer tool which can make it strings. I got to know about this while reviewing the volgen PR. You can take a look at it if it makes things simpler/easier for you.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me explore that, thanks. Is that libray already part of glusterd2?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that libray already part of glusterd2?

It's part of standard go tools and isn't an importable library. The volgen PR has example on how to use it. The stringer tool will generate code. All you have to do it include a one line comment in the go source file where you have your types (enum-like consts) defined. Example:

//go:generate stringer -type=GeorepStatus

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will include this in another patch later.


// GeorepSession represents Geo-replication session
type GeorepSession struct {
MasterID uuid.UUID `json:"master_volume_id"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if the string representation of UUID is what that is seen in response.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Sample output

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
X-Request-Id: 52e4ac7a-a470-4a9c-952f-687bebe442f0
Date: Thu, 12 Oct 2017 07:26:23 GMT
Content-Length: 255

{"master_volume_id":"254218fe-37ac-40e7-9b76-980700217862","slave_volume_id":"bc8834b4-c710-4fd6-b07e-f25380595a62","master_volume":"gv1","slave_user":"root","slave_hosts":["f26"],"slave_volume":"gv3","monitor_status":"Created","workers":[],"options":{}}

return route.Routes{
route.Route{
Name: "GeoreplicationCreate",
Method: "PUT",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I really prefer PUT over POST for resource creation and POST for resource modification.

But it's been POST for all requests in REST API so far. We should open up this for discussion. We will need the APIs to be uniform i.e creation of volumes, snapshot, georep to be all PUT or all POST.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, mastervolid and slaveid can also be part of request body. Any reason for it being part of URL ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, mastervolid and slaveid can also be part of request body. Any reason for it being part of URL ?

Since it is unique combination for a georep session and required always. It also makes more sense for other commands start/stop/status/config (Ex: POST /v1/geo-replication/:masterid/:slaveid/start)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change this to POST

}

// Validate UUID format of Master and Slave Volume ID
masterid, slaveid, err := validateMasterAndSlaveIDFormat(w, masteridRaw, slaveidRaw)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent with rest of the code, you can return SendHTTPError() from the handler itself.

 if uuid.Parse(masteridRaw) == nil || uuid.Parse(slaveidRaw) == nil {
    restutils.SendHTTPError(w, http.StatusBadRequest, "Invalid Master/Slave Volume ID")
    return
}

Or you can put all of the below validations (MasterVol, SlaveHosts, SlaveVol) in a single validation function. This will also make the handler function smaller and more readable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially I had that in handler itself, but observed that I have to repeat the stuff almost for all Georep API calls. (MasterVol, SlaveHosts and SlaveVol) validation is required only for Create/Update. For all the other apis Start/Stop/Delete/Status/Config we don't need to validate these fields except Master ID and Slave ID

return
}

geoSession = new(georepapi.GeorepSession)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider populating this struct instance (including members filled below) in it's own function, may be something like:

func newGeorepSession(req *georepapi.GeorepCreateRequest) *georepapi.GeorepSession

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

lock,
{
DoFunc: "georeplication-create.Commit",
Nodes: []uuid.UUID{gdctx.MyUUID},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this run only one node, is this made a transaction only for the locking ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some todos for Geo-rep create steps. I think I need to create a working directory in all Volume nodes before starting. I will work on those steps later.


geoSession.Status = georepapi.GeorepStatusCreated

e = addOrUpdateSession(geoSession)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this part of txnGeorepCreate ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will move this to txn

Copy link
Member Author

@aravindavk aravindavk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @prashanthpai for review comments, I will address the comments and refresh the patch.

package georeplication

// GeorepCreateRequest represents REST API request to create Geo-rep session
type GeorepCreateRequest struct {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SlaveUser is optional, if not provided defaults to "root"

"github.com/pborman/uuid"
)

const (
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me explore that, thanks. Is that libray already part of glusterd2?


// GeorepSession represents Geo-replication session
type GeorepSession struct {
MasterID uuid.UUID `json:"master_volume_id"`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Sample output

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
X-Request-Id: 52e4ac7a-a470-4a9c-952f-687bebe442f0
Date: Thu, 12 Oct 2017 07:26:23 GMT
Content-Length: 255

{"master_volume_id":"254218fe-37ac-40e7-9b76-980700217862","slave_volume_id":"bc8834b4-c710-4fd6-b07e-f25380595a62","master_volume":"gv1","slave_user":"root","slave_hosts":["f26"],"slave_volume":"gv3","monitor_status":"Created","workers":[],"options":{}}

return route.Routes{
route.Route{
Name: "GeoreplicationCreate",
Method: "PUT",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, mastervolid and slaveid can also be part of request body. Any reason for it being part of URL ?

Since it is unique combination for a georep session and required always. It also makes more sense for other commands start/stop/status/config (Ex: POST /v1/geo-replication/:masterid/:slaveid/start)

return route.Routes{
route.Route{
Name: "GeoreplicationCreate",
Method: "PUT",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change this to POST

}

// Validate UUID format of Master and Slave Volume ID
masterid, slaveid, err := validateMasterAndSlaveIDFormat(w, masteridRaw, slaveidRaw)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially I had that in handler itself, but observed that I have to repeat the stuff almost for all Georep API calls. (MasterVol, SlaveHosts and SlaveVol) validation is required only for Create/Update. For all the other apis Start/Stop/Delete/Status/Config we don't need to validate these fields except Master ID and Slave ID

return
}

geoSession = new(georepapi.GeorepSession)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

lock,
{
DoFunc: "georeplication-create.Commit",
Nodes: []uuid.UUID{gdctx.MyUUID},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some todos for Geo-rep create steps. I think I need to create a working directory in all Volume nodes before starting. I will work on those steps later.


geoSession.Status = georepapi.GeorepStatusCreated

e = addOrUpdateSession(geoSession)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will move this to txn

Copy link
Contributor

@prashanthpai prashanthpai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for now. I'd prefer you move a function from api package though.

@@ -54,3 +54,22 @@ type GeorepSession struct {
Workers []GeorepWorker `json:"workers"`
Options map[string]string `json:"options"`
}

// NewGeorepSession creates new instance of GeorepSession
func NewGeorepSession(mastervolid uuid.UUID, slavevolid uuid.UUID, req GeorepCreateReq) *GeorepSession {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be part of api package though which is supposed to contain only API requests and responses. In future, I hope we will be able to generate API doc from the package or generate package code from the API spec.

You can place this function near the handler. And if it's only invoked there, you can as well choose not export it.

REST API to create Geo-replication session create

    PUT /v1/geo-replication/:mastervolid/:slavevolid

Request body,

    {
        "mastervol": MASTER_VOL_NAME,
        "slavevol": SLAVE_VOL_NAME,
        "slavehosts": LIST_OF_SLAVE_HOSTS,
        "slaveuser": SLAVE_USER
    }

REST API to update Geo-replication session update

    POST /v1/geo-replication/:mastervolid/:slavevolid

Request body,

    {
        "mastervol": MASTER_VOL_NAME,
        "slavevol": SLAVE_VOL_NAME,
        "slavehosts": LIST_OF_SLAVE_HOSTS,
        "slaveuser": SLAVE_USER
    }

Updates: #271
Signed-off-by: Aravinda VK <avishwan@redhat.com>
Added a basic test for Georep create, also added restclient entry.
Georep apis are added to main restclient package itself since main
restclient can't be extended if it is separate package.

Updates: #271
Signed-off-by: Aravinda VK <avishwan@redhat.com>
Updates: #271
Signed-off-by: Aravinda VK <mail@aravindavk.in>
@aravindavk
Copy link
Member Author

@prashanthpai updated the patch, please check

@aravindavk aravindavk merged commit 9e96491 into gluster:master Oct 13, 2017
@aravindavk aravindavk deleted the georep_create branch October 13, 2017 09:52
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants