From 897f538a3c230aa64bbf23ca974cb2ee1969d57e Mon Sep 17 00:00:00 2001 From: Denis Kirillov Date: Thu, 7 Dec 2023 15:02:57 +0300 Subject: [PATCH] [#48] frostfsid: add GetSubjectByName method Signed-off-by: Denis Kirillov --- frostfsid/client/client.go | 20 ++++++++++++++++++++ frostfsid/config.yml | 1 + frostfsid/frostfsid_contract.go | 6 ++++++ rpcclient/frostfsid/client.go | 5 +++++ tests/frostfsid_client_test.go | 21 +++++++++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/frostfsid/client/client.go b/frostfsid/client/client.go index 6e78b99..e5a3841 100644 --- a/frostfsid/client/client.go +++ b/frostfsid/client/client.go @@ -95,6 +95,7 @@ const ( addSubjectKeyMethod = "addSubjectKey" removeSubjectKeyMethod = "removeSubjectKey" getSubjectByKeyMethod = "getSubjectByKey" + getSubjectByNameMethod = "getSubjectByName" getSubjectKeyByNameMethod = "getSubjectKeyByName" setSubjectKVMethod = "setSubjectKV" setSubjectNameMethod = "setSubjectName" @@ -305,6 +306,16 @@ func (c Client) GetSubjectByKey(key *keys.PublicKey) (*Subject, error) { return parseSubject(items) } +// GetSubjectByName gets subject by its name (namespace scope). +func (c Client) GetSubjectByName(namespace, subjectName string) (*Subject, error) { + items, err := unwrap.Array(c.act.Call(c.contract, getSubjectByNameMethod, namespace, subjectName)) + if err != nil { + return nil, err + } + + return parseSubject(items) +} + // GetSubjectKeyByName gets subject public key by its name (namespace scope). func (c Client) GetSubjectKeyByName(namespace, subjectName string) (*keys.PublicKey, error) { return unwrap.PublicKey(c.act.Call(c.contract, getSubjectKeyByNameMethod, namespace, subjectName)) @@ -518,10 +529,19 @@ func (c Client) ListNonEmptyNamespaces() ([]string, error) { } // Wait invokes underlying wait method on actor.Actor. +// Notice that "already exists" err value is treated as an error by this routine unlike actor.Waiter. func (c Client) Wait(tx util.Uint256, vub uint32, err error) (*state.AppExecResult, error) { + if err != nil { + return nil, err + } return c.act.Wait(tx, vub, err) } +// Waiter returns underlying actor.Waiter. +func (c Client) Waiter() actor.Waiter { + return c.act +} + // ParseGroupID fetch groupID from stack after creating group method invocation. func (c Client) ParseGroupID(res *state.AppExecResult, err error) (int64, error) { if err != nil { diff --git a/frostfsid/config.yml b/frostfsid/config.yml index 02ea164..0da01a3 100644 --- a/frostfsid/config.yml +++ b/frostfsid/config.yml @@ -9,6 +9,7 @@ safemethods: - "getSubject" - "getSubjectExtended" - "getSubjectByKey" + - "getSubjectByName" - "getSubjectKeyByName" - "listGroups" - "listGroupSubjects" diff --git a/frostfsid/frostfsid_contract.go b/frostfsid/frostfsid_contract.go index 2afcba0..ffb6dd4 100644 --- a/frostfsid/frostfsid_contract.go +++ b/frostfsid/frostfsid_contract.go @@ -407,6 +407,12 @@ func GetSubjectByKey(key interop.PublicKey) Subject { panic("subject not found") } +func GetSubjectByName(ns, name string) Subject { + key := GetSubjectKeyByName(ns, name) + addr := contract.CreateStandardAccount(key) + return GetSubject(addr) +} + func GetSubjectKeyByName(ns, name string) interop.PublicKey { if name == "" { panic("invalid or name") diff --git a/rpcclient/frostfsid/client.go b/rpcclient/frostfsid/client.go index 4c4a999..936c7fd 100644 --- a/rpcclient/frostfsid/client.go +++ b/rpcclient/frostfsid/client.go @@ -207,6 +207,11 @@ func (c *ContractReader) GetSubjectByKey(key *keys.PublicKey) ([]stackitem.Item, return unwrap.Array(c.invoker.Call(c.hash, "getSubjectByKey", key)) } +// GetSubjectByName invokes `getSubjectByName` method of contract. +func (c *ContractReader) GetSubjectByName(ns string, name string) ([]stackitem.Item, error) { + return unwrap.Array(c.invoker.Call(c.hash, "getSubjectByName", ns, name)) +} + // GetSubjectExtended invokes `getSubjectExtended` method of contract. func (c *ContractReader) GetSubjectExtended(addr util.Uint160) ([]stackitem.Item, error) { return unwrap.Array(c.invoker.Call(c.hash, "getSubjectExtended", addr)) diff --git a/tests/frostfsid_client_test.go b/tests/frostfsid_client_test.go index 952ba54..1f8f5aa 100644 --- a/tests/frostfsid_client_test.go +++ b/tests/frostfsid_client_test.go @@ -516,6 +516,27 @@ func TestFrostFSID_Client_UseCaseListNSSubjects(t *testing.T) { prettyPrintExtendedSubjects(res) } +func TestFrostFSID_Client_GetSubjectByName(t *testing.T) { + ffsid, cancel := initFrostfsIFClientTest(t) + defer cancel() + + key, addr := newKey(t) + subjName := "name" + + tx := ffsid.cli.StartTx() + err := tx.WrapCall(ffsid.cli.CreateSubjectCall(defaultNamespace, key.PublicKey())) + require.NoError(t, err) + err = tx.WrapCall(ffsid.cli.SetSubjectNameCall(addr, subjName)) + require.NoError(t, err) + ffsid.a.await(ffsid.cli.SendTx(tx)) + + subj, err := ffsid.cli.GetSubjectByName(defaultNamespace, subjName) + require.NoError(t, err) + require.Equal(t, subjName, subj.Name) + require.True(t, key.PublicKey().Equal(subj.PrimaryKey)) + require.Equal(t, defaultNamespace, subj.Namespace) +} + func prettyPrintExtendedSubjects(subjects []*client.SubjectExtended) { for _, subj := range subjects { var sb strings.Builder