-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Snapshot Create API #533
Merged
olivere
merged 2 commits into
olivere:release-branch.v5
from
wedneyyuri:feature/snapshot_create_api
May 29, 2017
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
// Copyright 2012-present Oliver Eilhard. All rights reserved. | ||
// Use of this source code is governed by a MIT-license. | ||
// See http://olivere.mit-license.org/license.txt for details. | ||
|
||
package elastic | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"net/url" | ||
"time" | ||
|
||
"gopkg.in/olivere/elastic.v5/uritemplates" | ||
) | ||
|
||
// SnapshotCreateService is documented at https://www.elastic.co/guide/en/elasticsearch/reference/5.x/modules-snapshots.html. | ||
type SnapshotCreateService struct { | ||
client *Client | ||
pretty bool | ||
repository string | ||
snapshot string | ||
masterTimeout string | ||
waitForCompletion *bool | ||
bodyJson interface{} | ||
bodyString string | ||
} | ||
|
||
// NewSnapshotCreateService creates a new SnapshotCreateService. | ||
func NewSnapshotCreateService(client *Client) *SnapshotCreateService { | ||
return &SnapshotCreateService{ | ||
client: client, | ||
} | ||
} | ||
|
||
// Repository is the repository name. | ||
func (s *SnapshotCreateService) Repository(repository string) *SnapshotCreateService { | ||
s.repository = repository | ||
return s | ||
} | ||
|
||
// Snapshot is the snapshot name. | ||
func (s *SnapshotCreateService) Snapshot(snapshot string) *SnapshotCreateService { | ||
s.snapshot = snapshot | ||
return s | ||
} | ||
|
||
// MasterTimeout is documented as: Explicit operation timeout for connection to master node. | ||
func (s *SnapshotCreateService) MasterTimeout(masterTimeout string) *SnapshotCreateService { | ||
s.masterTimeout = masterTimeout | ||
return s | ||
} | ||
|
||
// WaitForCompletion is documented as: Should this request wait until the operation has completed before returning. | ||
func (s *SnapshotCreateService) WaitForCompletion(waitForCompletion bool) *SnapshotCreateService { | ||
s.waitForCompletion = &waitForCompletion | ||
return s | ||
} | ||
|
||
// Pretty indicates that the JSON response be indented and human readable. | ||
func (s *SnapshotCreateService) Pretty(pretty bool) *SnapshotCreateService { | ||
s.pretty = pretty | ||
return s | ||
} | ||
|
||
// BodyJson is documented as: The snapshot definition. | ||
func (s *SnapshotCreateService) BodyJson(body interface{}) *SnapshotCreateService { | ||
s.bodyJson = body | ||
return s | ||
} | ||
|
||
// BodyString is documented as: The snapshot definition. | ||
func (s *SnapshotCreateService) BodyString(body string) *SnapshotCreateService { | ||
s.bodyString = body | ||
return s | ||
} | ||
|
||
// buildURL builds the URL for the operation. | ||
func (s *SnapshotCreateService) buildURL() (string, url.Values, error) { | ||
// Build URL | ||
path, err := uritemplates.Expand("/_snapshot/{repository}/{snapshot}", map[string]string{ | ||
"snapshot": s.snapshot, | ||
"repository": s.repository, | ||
}) | ||
if err != nil { | ||
return "", url.Values{}, err | ||
} | ||
|
||
// Add query string parameters | ||
params := url.Values{} | ||
if s.pretty { | ||
params.Set("pretty", "1") | ||
} | ||
if s.masterTimeout != "" { | ||
params.Set("master_timeout", s.masterTimeout) | ||
} | ||
if s.waitForCompletion != nil { | ||
params.Set("wait_for_completion", fmt.Sprintf("%v", *s.waitForCompletion)) | ||
} | ||
return path, params, nil | ||
} | ||
|
||
// Validate checks if the operation is valid. | ||
func (s *SnapshotCreateService) Validate() error { | ||
var invalid []string | ||
if s.repository == "" { | ||
invalid = append(invalid, "Repository") | ||
} | ||
if s.snapshot == "" { | ||
invalid = append(invalid, "Snapshot") | ||
} | ||
if len(invalid) > 0 { | ||
return fmt.Errorf("missing required fields: %v", invalid) | ||
} | ||
return nil | ||
} | ||
|
||
// Do executes the operation. | ||
func (s *SnapshotCreateService) Do(ctx context.Context) (*SnapshotCreateResponse, error) { | ||
// Check pre-conditions | ||
if err := s.Validate(); err != nil { | ||
return nil, err | ||
} | ||
|
||
// Get URL for request | ||
path, params, err := s.buildURL() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Setup HTTP request body | ||
var body interface{} | ||
if s.bodyJson != nil { | ||
body = s.bodyJson | ||
} else { | ||
body = s.bodyString | ||
} | ||
|
||
// Get HTTP response | ||
res, err := s.client.PerformRequest(ctx, "PUT", path, params, body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Return operation response | ||
ret := new(SnapshotCreateResponse) | ||
if err := json.Unmarshal(res.Body, ret); err != nil { | ||
return nil, err | ||
} | ||
return ret, nil | ||
} | ||
|
||
// SnapshotShardFailure stores information about failures that occurred during shard snapshotting process. | ||
type SnapshotShardFailure struct { | ||
Index string `json:"index"` | ||
IndexUUID string `json:"index_uuid"` | ||
ShardID int `json:"shard_id"` | ||
Reason string `json:"reason"` | ||
NodeID string `json:"node_id"` | ||
Status string `json:"status"` | ||
} | ||
|
||
// SnapshotCreateResponse is the response of SnapshotCreateService.Do. | ||
type SnapshotCreateResponse struct { | ||
// Accepted indicates whether the request was accepted by elasticsearch. | ||
// It's available when waitForCompletion is false. | ||
Accepted *bool `json:"accepted"` | ||
|
||
// Snapshot is available when waitForCompletion is true. | ||
Snapshot *struct { | ||
Snapshot string `json:"snapshot"` | ||
UUID string `json:"uuid"` | ||
VersionID int `json:"version_id"` | ||
Version string `json:"version"` | ||
Indices []string `json:"indices"` | ||
State string `json:"state"` | ||
Reason string `json:"reason"` | ||
StartTime time.Time `json:"start_time"` | ||
StartTimeInMillis int64 `json:"start_time_in_millis"` | ||
EndTime time.Time `json:"end_time"` | ||
EndTimeInMillis int64 `json:"end_time_in_millis"` | ||
DurationInMillis int64 `json:"duration_in_millis"` | ||
Failures []SnapshotShardFailure `json:"failures"` | ||
Shards shardsInfo `json:"shards"` | ||
} `json:"snapshot"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package elastic | ||
|
||
import ( | ||
"net/url" | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func TestSnapshotValidate(t *testing.T) { | ||
var client *Client | ||
|
||
err := NewSnapshotCreateService(client).Validate() | ||
got := err.Error() | ||
expected := "missing required fields: [Repository Snapshot]" | ||
if got != expected { | ||
t.Errorf("expected %q; got: %q", expected, got) | ||
} | ||
} | ||
|
||
func TestSnapshotPutURL(t *testing.T) { | ||
client := setupTestClient(t) | ||
|
||
tests := []struct { | ||
Repository string | ||
Snapshot string | ||
Pretty bool | ||
MasterTimeout string | ||
WaitForCompletion bool | ||
ExpectedPath string | ||
ExpectedParams url.Values | ||
}{ | ||
{ | ||
Repository: "repo", | ||
Snapshot: "snapshot_of_sunday", | ||
Pretty: true, | ||
MasterTimeout: "60s", | ||
WaitForCompletion: true, | ||
ExpectedPath: "/_snapshot/repo/snapshot_of_sunday", | ||
ExpectedParams: url.Values{ | ||
"pretty": []string{"1"}, | ||
"master_timeout": []string{"60s"}, | ||
"wait_for_completion": []string{"true"}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
path, params, err := client.SnapshotCreate(test.Repository, test.Snapshot). | ||
Pretty(test.Pretty). | ||
MasterTimeout(test.MasterTimeout). | ||
WaitForCompletion(test.WaitForCompletion). | ||
buildURL() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if path != test.ExpectedPath { | ||
t.Errorf("expected %q; got: %q", test.ExpectedPath, path) | ||
} | ||
if !reflect.DeepEqual(params, test.ExpectedParams) { | ||
t.Errorf("expected %q; got: %q", test.ExpectedParams, params) | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
*struct
, although valid, doesn't look that good. Does ES always send back thesnapshot
? We have to look it up in the Java source. If it does, we should make it a normalstruct
, not a pointer to a struct.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, ES does not send the
snapshot
field whenwaitForCompletion
is false.https://github.com/elastic/elasticsearch/blob/45d4938fcc8f1a4cf988e119d7dd23bb2920b9e2/core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java#L87