frostfs-node/pkg/innerring/processors/netmap/nodevalidation/locode/calls.go
Leonard Lyubich bcfd33d9fb [#397] ir: Make UN-LOCODE attribute of the network map candidate optional
Previously UN-LOCODE attribute was required for each network map candidate.
In the absence of this attribute, the candidate was not allowed into the
network map. After revising the requirements for candidates, it was decided
not to require the mandatory installation of the attribute by candidates.

From now inner ring does not modify location attributes of the network map
candidate in the absence of UN-LOCODE attribute and does not block entry
into the network map for this criterion.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2021-02-25 14:36:11 +03:00

84 lines
2 KiB
Go

package locode
import (
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
"github.com/nspcc-dev/neofs-node/pkg/util/locode"
"github.com/pkg/errors"
)
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 errors.Wrap(err, "invalid locode value")
}
record, err := v.db.Get(lc)
if err != nil {
return errors.Wrap(err, "could not get locode record from DB")
}
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
}