frostfs-node/pkg/innerring/processors/netmap/nodevalidation/locode/calls.go
Evgenii Stratonikov 71b87155ef [#521] *: use stdlib errors package
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2021-05-19 16:42:54 +03:00

86 lines
2 KiB
Go

package locode
import (
"errors"
"fmt"
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
"github.com/nspcc-dev/neofs-node/pkg/util/locode"
)
var errMissingRequiredAttr = errors.New("missing required attribute in DB record")
// VerifyAndUpdate validates UN-LOCODE attribute of n
// and adds a group of related attributes.
//
// If n does not contain UN-LOCODE attribute, nil is returned
// without any actions. Otherwise, if UN-LOCODE value does not
// match the UN/LOCODE format, an error returns.
//
// New attributes are formed from the record of DB instance (Prm).
// If DB entry R was found w/o errors, then new attributes are:
// * CountryCode: R.CountryCode().String();
// * Country: R.CountryName();
// * LocationCode: R.LocationCode().String();
// * Location: Record.LocationName();
// * SubDivCode: R.SubDivCode();
// * SubDiv: R.SubDivName();
// * Continent: R.Continent().String().
//
// UN-LOCODE attribute remains untouched.
func (v *Validator) VerifyAndUpdate(n *netmap.NodeInfo) error {
mAttr := uniqueAttributes(n.Attributes())
attrLocode, ok := mAttr[netmap.AttrUNLOCODE]
if !ok {
return nil
}
lc, err := locode.FromString(attrLocode.Value())
if err != nil {
return fmt.Errorf("invalid locode value: %w", err)
}
record, err := v.db.Get(lc)
if err != nil {
return fmt.Errorf("could not get locode record from DB: %w", err)
}
for attrKey, attrDesc := range v.mAttr {
attrVal := attrDesc.converter(record)
if attrVal == "" {
if !attrDesc.optional {
return errMissingRequiredAttr
}
continue
}
a := netmap.NewNodeAttribute()
a.SetKey(attrKey)
a.SetValue(attrVal)
mAttr[attrKey] = a
}
as := n.Attributes()
as = as[:0]
for _, attr := range mAttr {
as = append(as, attr)
}
n.SetAttributes(as...)
return nil
}
func uniqueAttributes(as []*netmap.NodeAttribute) map[string]*netmap.NodeAttribute {
mAttr := make(map[string]*netmap.NodeAttribute, len(as))
for _, attr := range as {
mAttr[attr.Key()] = attr
}
return mAttr
}