This is an automated email from the ASF dual-hosted git repository.
miaoliyao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/shardingsphere-on-cloud.git
The following commit(s) were added to refs/heads/main by this push:
new 0c75c0b feat(pitr):local storage,add some query method (#247)
0c75c0b is described below
commit 0c75c0bf42e135ebaa71576289f5c393c25b9c89
Author: lltgo <[email protected]>
AuthorDate: Tue Mar 7 18:32:46 2023 +0800
feat(pitr):local storage,add some query method (#247)
---
pitr/cli/internal/pkg/local-storage.go | 71 ++++++++++++++++++++--
pitr/cli/internal/pkg/local-storage_test.go | 94 ++++++++++++++++++++++++++---
pitr/cli/internal/pkg/model/ls_backup.go | 81 +++++++++++++++++++++++++
pitr/cli/internal/pkg/xerr/err.go | 1 +
4 files changed, 234 insertions(+), 13 deletions(-)
diff --git a/pitr/cli/internal/pkg/local-storage.go
b/pitr/cli/internal/pkg/local-storage.go
index 329fa76..1d8a74a 100644
--- a/pitr/cli/internal/pkg/local-storage.go
+++ b/pitr/cli/internal/pkg/local-storage.go
@@ -19,7 +19,10 @@ package pkg
import (
"encoding/json"
+ "errors"
"fmt"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/model"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/xerr"
"os"
"strings"
"time"
@@ -35,12 +38,13 @@ type (
ILocalStorage interface {
init() error
- WriteByJSON(name string, contents anyStruct) error
+ WriteByJSON(name string, contents *model.LsBackup) error
GenFilename(extn extension) string
+ ReadAll() ([]model.LsBackup, error)
+ ReadByID(id string) (*model.LsBackup, error)
+ ReadByCSN(csn string) (*model.LsBackup, error)
}
- anyStruct any
-
extension string
)
@@ -97,7 +101,7 @@ func (ls *localStorage) init() error {
return nil
}
-func (ls *localStorage) WriteByJSON(name string, contents anyStruct) error {
+func (ls *localStorage) WriteByJSON(name string, contents *model.LsBackup)
error {
if !strings.HasSuffix(name, ".json") {
return fmt.Errorf("wrong file extension,file name is %s", name)
}
@@ -121,6 +125,65 @@ func (ls *localStorage) WriteByJSON(name string, contents
anyStruct) error {
return nil
}
+func (ls *localStorage) ReadAll() ([]model.LsBackup, error) {
+ entries, err := os.ReadDir(ls.backupDir)
+ if err != nil {
+ return nil, xerr.NewCliErr(fmt.Sprintf("read the dir[path:%s]
failed,err=%s", ls.backupDir, err))
+ }
+ backups := make([]model.LsBackup, 0, len(entries))
+ for _, entry := range entries {
+ if entry.IsDir() {
+ continue
+ }
+
+ info, err := entry.Info()
+ if errors.Is(err, os.ErrNotExist) {
+ return nil, xerr.NewCliErr("The file does not exist or
has changed")
+ } else if err != nil {
+ return nil, xerr.NewCliErr(fmt.Sprintf("Unknown err:get
entry info failed,err=%s", err))
+ }
+
+ path := fmt.Sprintf("%s/%s", ls.backupDir, info.Name())
+ file, err := os.ReadFile(path)
+ if err != nil {
+ return nil, xerr.NewCliErr(fmt.Sprintf("read file
failed,err=%s", err))
+ }
+
+ b := model.LsBackup{}
+ if err := json.Unmarshal(file, &b); err != nil {
+ return nil, xerr.NewCliErr(fmt.Sprintf("invalid
contents[filePath=%s],err=%s", path, err))
+ }
+ backups = append(backups, b)
+ }
+ return backups, nil
+}
+
+func (ls *localStorage) ReadByCSN(csn string) (*model.LsBackup, error) {
+ list, err := ls.ReadAll()
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range list {
+ if v.Info.CSN == csn {
+ return &v, nil
+ }
+ }
+ return nil, xerr.NewCliErr(xerr.NotFound)
+}
+
+func (ls *localStorage) ReadByID(id string) (*model.LsBackup, error) {
+ list, err := ls.ReadAll()
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range list {
+ if v.Info.ID == id {
+ return &v, nil
+ }
+ }
+ return nil, xerr.NewCliErr(xerr.NotFound)
+}
+
/*
GenFilename gen a filename based on the file extension
diff --git a/pitr/cli/internal/pkg/local-storage_test.go
b/pitr/cli/internal/pkg/local-storage_test.go
index a691ff1..40e1d72 100644
--- a/pitr/cli/internal/pkg/local-storage_test.go
+++ b/pitr/cli/internal/pkg/local-storage_test.go
@@ -19,7 +19,10 @@ package pkg
import (
"fmt"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/model"
+ "github.com/google/uuid"
"os"
+ "time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@@ -35,6 +38,47 @@ var _ = Describe("ILocalStorage", func() {
Expect(ls).NotTo(BeNil())
})
+ It("ReadALL", func() {
+ Skip("Manually exec:dependent environment")
+ root := fmt.Sprintf("%s/%s", os.Getenv("HOME"),
".gs_pitr")
+ ls, err := NewLocalStorage(root)
+ Expect(err).To(BeNil())
+ Expect(ls).NotTo(BeNil())
+
+ list, err := ls.ReadAll()
+ Expect(err).To(BeNil())
+ fmt.Println(fmt.Sprintf("%+v", list))
+ for _, v := range list {
+ fmt.Println(fmt.Sprintf("%+v", v.Info))
+ }
+ })
+
+ It("ReadByCSN", func() {
+ Skip("Manually exec:dependent environment")
+ root := fmt.Sprintf("%s/%s", os.Getenv("HOME"),
".gs_pitr")
+ ls, err := NewLocalStorage(root)
+ Expect(err).To(BeNil())
+ Expect(ls).NotTo(BeNil())
+
+ backup, err :=
ls.ReadByCSN("e19b6935-c437-4cf0-b820-3275bd2727a2")
+ Expect(err).To(BeNil())
+ fmt.Println(fmt.Sprintf("%+v", backup))
+ fmt.Println(fmt.Sprintf("%+v", backup.Info))
+ })
+
+ It("ReadByID", func() {
+ Skip("Manually exec:dependent environment")
+ root := fmt.Sprintf("%s/%s", os.Getenv("HOME"),
".gs_pitr")
+ ls, err := NewLocalStorage(root)
+ Expect(err).To(BeNil())
+ Expect(ls).NotTo(BeNil())
+
+ backup, err :=
ls.ReadByID("66785e18-b8d3-42f4-9967-a4119be15cea")
+ Expect(err).To(BeNil())
+ fmt.Println(fmt.Sprintf("%+v", backup))
+ fmt.Println(fmt.Sprintf("%+v", backup.Info))
+ })
+
It("GenFilename and WriteByJSON", func() {
Skip("Manually exec:dependent environment")
root := fmt.Sprintf("%s/%s", os.Getenv("HOME"),
".gs_pitr")
@@ -45,16 +89,48 @@ var _ = Describe("ILocalStorage", func() {
filename := ls.GenFilename(ExtnJSON)
Expect(filename).NotTo(BeEmpty())
- type T struct {
- Name string
- Age uint8
- }
-
- contents := T{
- Name: "Pikachu",
- Age: 65,
+ contents := model.LsBackup{
+ Info: &model.BackupMetaInfo{
+ ID: uuid.New().String(),
+ CSN: uuid.New().String(),
+ StartTime: time.Now().Unix(),
+ Endtime:
time.Now().Add(time.Minute).Unix(),
+ },
+ DnList: []model.DataNode{
+ {
+ IP: "1.1.1.1",
+ Port: "5432",
+ Status: "Completed",
+ BackupID: "SK08DAK1",
+ StartTime: time.Now().Unix(),
+ Endtime: time.Now().Unix(),
+ },
+ {
+ IP: "1.1.1.2",
+ Port: "5432",
+ Status: "Completed",
+ BackupID: "SK08DAK2",
+ StartTime: time.Now().Unix(),
+ Endtime: time.Now().Unix(),
+ },
+ },
+ SsBackup: &model.SsBackup{
+ Status: "Completed",
+ ClusterInfo: model.ClusterInfo{
+ MetaData: model.MetaData{
+ Databases:
model.Databases{
+ ShardingDb:
"ShardingDb",
+ AnotherDb:
"AnotherDb",
+ },
+ Props: "Props",
+ Rules: "Rules",
+ },
+ SnapshotInfo:
model.SnapshotInfo{},
+ },
+ StorageNodes: nil,
+ },
}
- err = ls.WriteByJSON(filename, contents)
+ err = ls.WriteByJSON(filename, &contents)
Expect(err).To(BeNil())
})
})
diff --git a/pitr/cli/internal/pkg/model/ls_backup.go
b/pitr/cli/internal/pkg/model/ls_backup.go
new file mode 100644
index 0000000..547d688
--- /dev/null
+++ b/pitr/cli/internal/pkg/model/ls_backup.go
@@ -0,0 +1,81 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+ */
+
+package model
+
+type (
+ // LsBackup LocalStorageBackup
+ LsBackup struct {
+ Info *BackupMetaInfo `json:"info"`
+ DnList []DataNode `json:"dn_list"`
+ SsBackup *SsBackup `json:"ss_backup"`
+ }
+
+ BackupMetaInfo struct {
+ ID string `json:"id"`
+ CSN string `json:"csn"`
+ StartTime int64 `json:"start_time"` // Unix time
+ Endtime int64 `json:"end_time"` // Unix time
+ }
+
+ DataNode struct {
+ IP string `json:"ip"`
+ Port string `json:"port"`
+ Status string `json:"status"`
+ BackupID string `json:"backup_id"`
+ StartTime int64 `json:"start_time"` // Unix time
+ Endtime int64 `json:"end_time"` // Unix time
+ }
+)
+
+type (
+ SsBackup struct {
+ Status string `json:"status"`
+ ClusterInfo ClusterInfo `json:"cluster_info"`
+ StorageNodes []StorageNodes `json:"storage_nodes"`
+ }
+
+ ClusterInfo struct {
+ MetaData MetaData `json:"meta_data"`
+ SnapshotInfo SnapshotInfo `json:"snapshot_info"`
+ }
+
+ StorageNodes struct {
+ IP string `json:"ip"`
+ Port string `json:"port"`
+ Username string `json:"username"`
+ Password string `json:"password"`
+ Database string `json:"database"`
+ Remark string `json:"remark"`
+ }
+
+ MetaData struct {
+ Databases Databases `json:"databases"`
+ Props string `json:"props"`
+ Rules string `json:"rules"`
+ }
+
+ Databases struct {
+ ShardingDb string `json:"sharding_db"`
+ AnotherDb string `json:"another_db"`
+ }
+
+ SnapshotInfo struct {
+ Csn string `json:"csn"`
+ CreateTime string `json:"create_time"`
+ }
+)
diff --git a/pitr/cli/internal/pkg/xerr/err.go
b/pitr/cli/internal/pkg/xerr/err.go
index d9302f8..6a09aeb 100644
--- a/pitr/cli/internal/pkg/xerr/err.go
+++ b/pitr/cli/internal/pkg/xerr/err.go
@@ -29,6 +29,7 @@ type (
const (
Unknown = "Unknown error"
InvalidHttpStatus = "Invalid http status"
+ NotFound = "Not found"
)
func (e *err) Error() string {